I can't seem to get set anything for
req.session
I'm trying to store oauth token and the secret into a session so i can check them after the authorize callback. Here is my code
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server),
oauth = require('oauth'),
tumblr = require('tumblr.js'),
client = {
consumer_key: '1n9fMPxCBFBbcIGRImYKSK5wwDL6yux64S4DxEwiwzHTNuaIoD',
consumer_secret: 'bW9YKbnwgxexyVx1AaxQr1QoemEkjd29p5U1WpbZ8r1XEH41C0'
},
consumer = new oauth.OAuth(
"http://www.tumblr.com/oauth/request_token", "http://www.tumblr.com/oauth/access_token",
client.consumer_key, client.consumer_secret, "1.0A", "http://127.0.0.1:8080/sessions/callback", "HMAC-SHA1");
server.listen(1337);
app.configure('dev', function(){
app.use(express.logger());
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: "topsecret" }));
});
app.get('/home', function(req, res){
consumer.getOAuthRequestToken(function(err, oauth_token, oauth_token_secret, results){
if(err){
console.log(err);
}else{
//req.session.oauth.token = oauth_token;
console.log('oauth.token: ' + oauth_token);
//req.session.oauth.token_secret = oauth_token_secret;
console.log('oauth.token_secret: ' + oauth_token_secret);
res.redirect('http://www.tumblr.com/oauth/authorize?oauth_token='+oauth_token);
}
});
});
app.get('/oauth/testapp', function(req, res){
res.send('callback');
});
When I uncomment
req.session.oauth.token = oauth_token;
I get an error "cannot read property 'oauth' of undefined" also req.session displays undefined in the console.
You're trying to set the property token on an object oauth on the session. If the oauth object is not initialized, it will be undefined, and you can't set the token attribute. You first need to initialize the oauth object in the session. You could for instance do
req.session.oauth = {token: theToken}
This will create an object in the session and also set the token property of that object.
#robertklep figured out the other half of the solution: Make sure you're running with the correct environment. Since you have used dev in app.configure, you have to run node with NODE_ENV=dev for the configuration to be applied.
var app = express();
app.configure('dev', function() {
app.use(express.logger());
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: "topsecret" }));
app.use(app.router); // You need to add the router after the express.session
});
hope this can help you
Related
I am learning JWT with NodeJs. I am stuck at passing the JWT in header actually i do not know how to do this.
index.js file
var express = require('express'),
app = express(),
routes = require('./routes'),
bodyParser = require('body-parser'),
path = require('path'),
ejs = require('ejs'),
jwt = require('jsonwebtoken');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.post('/home',routes.loginUser);
app.get('/', function(req, res) {
res.render('index');
});
app.get('/home',function(req, res) {
jwt.verify(req.token, 'qwertyu6456asdfghj', function(err, data) {
if (err) {
res.sendStatus(403);
}
});
});
app.listen(3000,function(){
console.log("Server running at Port 3000");
});
routes/index.js file
var jwt = require('jsonwebtoken');
exports.home = function(req, res){
res.render('home',{error: false});
};
exports.loginUser = function(req, res) {
var uname = req.body.Username;
var pwd = req.body.Password;
if(uname && pwd === 'admin'){
res.render('home');
var token = jwt.sign({ user: uname }, 'qwertyuiopasdfghj');
console.log('Authentication is done successfully.....');
console.log(token);
}
response.json({
authsuccess: true,
description: 'Sending the Access Token',
token: token
});
};
when i run the application i am getting the token in console.log but
How can I pass token in header and store it in localStorage of browser?
So you want to send the token to frontend but not in the body.
The Recommended way to do so is to use cookies. You can set the token in the cookie and it can be automatically accessed in front-end and in the backend.
res.cookie('tokenKey', 'ajsbjabcjcTOKENajbdcjabdcjdc');
Using authorization headers is also a good approach, but again, in front-end, you have to fetch the token from headers and then save in localStorage or cookie, which you don't have to do in case of cookie.
res.header(field [, value]);
As #ChicoDelaBarrio told you, it depends on the client. Postman is a good place to start checking your backend. But after you have your server working, you have to start working in your client side.
If you want a complete backend example about JWT in Node.js, with Refresh token included, I recomend you this post about it: Refresh token with JWT authentication in Node.js
Probably you can reuse most of the code. In this case the header is not created with BEARER, but with JWT at the beginning, but it works the same
There are many questions relating to getting a req.user undefined after social authentication, but I found none which could help me.
I have been able to successfully use the example for using passport for twitter authentication: https://github.com/passport/express-4.x-twitter-example. I tried to follow this pattern as closely as possible but cannot seem to get it to work.
Specifically, I am able to successfully authenticate, but the req.user is undefined. This makes no sense to me as my user data was returned no problem from the example.
I'm not inclined to believe this is a middleware problem (as it has been for others) as the middleware is the same as that used in the example. It could be something about having multiple domains, but I'm not sure what. All of this is being done on the localhost.
In Twitter, the app is set up so that
website is: 127.0.0.1:3000/signin
and the
callback url is: 127.0.0.1:2999/auth/twitter/return
As you can tell, my client is working on port 3000 and it is making calls to a server running on port 2999.
To briefly walk you through the code, the client on 127.0.0.1:3000/signin has a button which links to 127.0.0.1:2999/auth/twitter, thus initiating the authentication request. Under the hood, the express server is created in server/index.js--server. This imports the routes in routes/index.js, some of which the controller authenticate.js handles. As you can see, the oauth twitter request is made in authenticate.js. Again, authentication proceeds successfully, I am redirected to 127.0.0.1:3000/search. However, as you can see in this.twitter_callback, I am printing the req.user and it is undefined.
Please note that I have redacted the consumer key/secret from my code.
server/index.js
var cors = require('cors')
var bodyParser = require('body-parser')
var express = require('express');
var app = express();
var http = require('http').Server(app)
var io = require('socket.io')(http)
// NOT SURE WHY I NEED TO GO BACK 3 FOLDERS TO GET TO PORT_CONFIG
var port = require("../port_config.json").server_port;
var PORT = Number(process.env.PORT || port);
var routes = require('./routes/index.js')
var database = require('./database/db.js')
var db = new database()
app.use(cors()); // middleware that allows cross-platform requests
app.use(bodyParser.json());
db.dbConnect(function(err,db_instance){
// routes
routes(app, db_instance, io)
// send user polls on connection
// TEMPORARY (WILL BE GRABBED ON LOGIN)
var user = null // WILL BE SET AFTER LOGIN
io.on('connection', function(socket) {
var places_attending = db_instance.collection('places_attending')
places_attending.find({}).toArray(function(err,docs){
var places_user_attending = docs.map(doc => {
if (doc.attending.indexOf(user) !== -1) {
return {
id: doc.id,
name: doc.name,
num_attending: doc.attending.length
}
}
})
socket.emit('places_user_attending', places_user_attending);
})
})
})
http.listen(PORT, function () {
console.log('Backend server listening at http://localhost:' + PORT);
})
module.exports = http
routes/index.js
var Search = require('../controllers/search.js')
var Add = require('../controllers/add.js')
var Authenticate = require('../controllers/authenticate.js')
module.exports = function(app, db, io) {
var search = new Search(db, io)
var add = new Add(db, io)
var authenticate = new Authenticate(app)
app.route('/api/search')
.post(search.search_yelp)
app.route('/api/add')
.post(add.add_attendee)
app.route('/auth/twitter')
.get(authenticate.twitter_authentication)
app.route('/auth/twitter/return')
.get(authenticate.twitter_callback)
}
authenticate.js
function authenticate(app) {
var passport = require('passport');
var Strategy = require('passport-twitter').Strategy;
// Configure the Twitter strategy for use by Passport.
passport.use(new Strategy({
consumerKey: REDACTED,
consumerSecret: REDACTED,
callbackURL: 'http://127.0.0.1:2999/auth/twitter/return'
},
function(token, tokenSecret, profile, cb) {
// In this example, the user's Twitter profile is supplied as the user
// record. In a production-quality application, the Twitter profile should
// be associated with a user record in the application's database, which
// allows for account linking and authentication with other identity
// providers.
return cb(null, profile);
}));
// Configure Passport authenticated session persistence.
passport.serializeUser(function(user, cb) {
cb(null, user);
});
passport.deserializeUser(function(obj, cb) {
cb(null, obj);
});
// Use application-level middleware for common functionality, including
// logging, parsing, and session handling.
app.use(require('morgan')('combined'));
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({ secret: 'keyboard cat', resave: true, saveUninitialized: true }));
// Initialize Passport and restore authentication state, if any, from the
// session.
app.use(passport.initialize());
app.use(passport.session());
this.twitter_authentication = passport.authenticate('twitter')
this.twitter_callback = (
passport.authenticate('twitter', { failureRedirect: 'http://127.0.0.1:3000/signin' }),
function(req, res) {
console.log('REQ.USER OBJECT: ' + req.user)
res.redirect('http://127.0.0.1:3000/search');
}
)
}
module.exports = authenticate
Any help would be greatly, greatly appreciated.
The problem was in how my twitter_callback route was specified.
If I change the callback to this:
this.twitter_callback = app.get('/auth/twitter/return',
passport.authenticate('twitter', { failureRedirect: 'http://127.0.0.1:3000/signin' }),
function(req, res) {
console.log(req.user)
res.redirect('http://127.0.0.1:3000/search');
})
everything works fine. I think this has something to do with the middleware not being applied correctly the initial way I wrote it. Not exactly sure how I would rewrite it to export it, without using app.get in the twitter_callback though
I'm trying to verify a signed token and extract information from it using NodeJS.
I have a token named userToken in the browser right now, it has been saved after I logged in (I use auth0 to login by the way).
I tried to verify my token here manually : http://jwt.io , it works and gives me payload data without a problem. However, I can't do the same thing with NodeJS. How can I do it?
I read the docs but I couldn't get it.
https://github.com/auth0/express-jwt
Here's my server.js
var http = require('http');
var express = require('express');
var cors = require('cors');
var app = express();
var jwt = require('express-jwt');
var dotenv = require('dotenv');
dotenv.load();
var authenticate = jwt({
secret: new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64'),
audience: process.env.AUTH0_CLIENT_ID
});
// view engine setup
var path = require('path');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'jade');
app.configure(function () {
// Request body parsing middleware should be above methodOverride
app.use(express.bodyParser());
app.use(express.urlencoded());
app.use(express.json());
app.use(cors());
app.use(app.router);
});
app.get('/', function (req, res) {
res.render('index');
});
app.get('/test', function(req,res) {
// how do I check it?
});
var port = process.env.PORT || 3001;
http.createServer(app).listen(port, function (err) {
console.log('listening in http://localhost:' + port);
});
You dont't need to implement nothing. Since you are using this express-jwt, just pass the userProperty tag to jwt:
var authenticate = jwt({
secret: new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64'),
audience: process.env.AUTH0_CLIENT_ID,
userProperty: 'payload'
});
So, you can get all of your jwt payload data using req.payload in your controllers. You can check it with console.log(req.payload).
You can see how it works here: https://github.com/auth0/express-jwt/blob/master/lib/index.js#L121
I hope it helps, and sorry about my English.
This sample should help you, it's not tested, but sure it's right way, look at source of express-jwt, it does literally same behind the scenes
app.get('/test', function(req, res) {
var jsonwebtoken = require('jsonwebtoken'); //install this, move to declarations
var loginToken = req.headers.authentication || req.body.userToken || req.headers.Bearer; //or your own, it's just headers that pass from browser to client
jsonwebtoken.verify(loginToken, new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64'), function(err, decoded) {
if(err) {
return res.status(401).send({message: 'invalid_token'});
}
//be aware of encoded data structure, simply console.log(decoded); to see what it contains
res.send(decoded); //`decoded.foo` has your value
});
});
The thing is that you must yourself encode your data, and then decode, so be aware that auth0 returns valid data structure for you (as i'm not sure otherwise)
After setting up the Drupal as this guide says: Drupal-passport I created a simple simple node app to test how it works.
It doesn't, I get the InternalOAuthError: Failed to obtain request token error.
Going through the strategy.js, I saw that my callbackURL is logging out undefined not exactly sure why. The callbackURL is set in my Drupal app
Also preforming a curl -i -XPOST http://extranet.local/rest/system/connect/ gives me exactly what I need
Here is my node.js code (keep in mind this is just supposed to test the drupal set up).
var express = require('express');
var passport = require('passport');
var dStrategy = require('passport-drupal').DrupalStrategy;
var passportDrupal = require('passport-drupal');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser')
var session = require('express-session');
var http = require('http');
var app = express();
var server = http.createServer(app);
app.use(cookieParser());
app.use(bodyParser());
app.use(session({ secret: 'SECRET' }));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new dStrategy({
consumerKey: "emDVp7P2LZFLPcN3cNCjLmrjrhQLnNv6",
consumerSecret: "mkbc3UYEuUQLNQRwLWo3B8zEk4ZrErKa",
providerURL: "http://extranet.local",
resourceEndpoint: "rest/system/connect", // <---- optional. Defaults to `rest/system/connect`
callbackURL: 'http://33.33.33.40:8888/auth/drupal/callback'
},
function(token, tokenSecret, profile, done) {
profile.oauth = { token: token, token_secret: tokenSecret };
done(null, profile);
}
));
app.get('/', function(req, res) {
res.writeHead(200);
res.end("This is root");
});
app.get('/auth/drupal',
passport.authenticate('drupal'),
function(req, res) {
// The request will be redirected to the Drupal website for
// authentication, so this function will not be called.
});
app.get('/auth/drupal/callback',
passport.authenticate('drupal', { failureRedirect: '/error' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/signedin');
});
app.get('/error', function(req, res) {
res.writeHead(200);
res.end("Could not sign in");
});
app.get('/signedin', function(req, res) {
res.writeHead(200);
res.end("signed in");
});
server.listen(8888, '33.33.33.40');
Any clues as to why or ideas are greatly appreciated
If you look into the strategy.js code of the library passport-drupal, you will see that the DrupalStrategy constructor does not expect a callbackURL property in the options parameter object and it also does not pass it further into the OAuthStrategy.
This is the code snippet that creates the parameter for the oauth strategy:
// Determine all necessary OAuth options
var oauthOptions = {
requestTokenURL: this._providerURL + '/oauth/request_token',
accessTokenURL: this._providerURL + '/oauth/access_token',
userAuthorizationURL: this._providerURL + '/oauth/authorize',
consumerKey: options.consumerKey,
consumerSecret: options.consumerSecret
};
OAuthStrategy.call(this, oauthOptions, verify);
It should be modified to pass the callbackURL, for example like this:
// Determine all necessary OAuth options
var oauthOptions = {
requestTokenURL: this._providerURL + '/oauth/request_token',
accessTokenURL: this._providerURL + '/oauth/access_token',
userAuthorizationURL: this._providerURL + '/oauth/authorize',
consumerKey: options.consumerKey,
consumerSecret: options.consumerSecret,
callbackURL: options.callbackURL// <==== THIS LINE WAS ADDED
};
OAuthStrategy.call(this, oauthOptions, verify);
I'm not sure that will solve your issue though. But I made a pull request
I have been staring at the same SO questions/answers for too long.
I am trying to set my user ID in a req.session variable
here is my app.js stack
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, cors = require('cors')
, mongoose = require('mongoose')
, User = require('./user-model')
, path = require('path')
, mysql = require('mysql');
app = express()
/**
* Middleware.
*/
app.use(cors());
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'supercalafragalistic' }));
app.locals.pretty = true;
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'jade');
...
app.get('/someRoute', routes.someRoute)
I have moved the app.router from top to bottom. Currently it is implied (I just deleted it as I stripped my code looking for error). I have exported app, included app in routes (also erased) . I added middleware. I am lost.....
here is my route stack
//routes/index.js
//requires
var User = require('../user-model')
,qs = require('querystring')
,http = require('http')
,mysql = require('mysql')
,connection = mysql.createConnection({
edited
});
/**
* Set up application.
*/
connection.connect(function(err){
if(err) console.log('failed to connect to mysql because'+ err);
else console.log('connected to mysql');
})
I save the id in the login route:
//login processing route
exports.logIn = function(req, res, next){
console.log('log in request from '+req.body.name);
User.findOne({name:req.body.name}, function(err, user, next){
if(err) return next(err);
if(!user) return res.end();
//check password
user.comparePassword(req.body.password, function(err, isMatch){
if(err) res.send('failed to find user');
console.log(""+isMatch);
if(isMatch){
console.log(user._id.toString()+' user loggd in');
//set session cookie
req.session.loggedIn = user._id.toString();
console.log('req.session.loggedIn set to :'+req.session.loggedIn );
res.send(user);
}else {
res.send('User not found try again');
}
});
});
However, in all other routes the variable is undefined:
// clock status
exports.clockStatus = function(req, res, next){
var user = req.session.loggedIn;
console.log('Status route, userID: '+user);
if(user){
I found the answer in "Cannot access req.session variables in Express/NodeJS" but the last part trails off:
In your case, you have assigned req.session.user = user; only in
/login request. It will not be available for further requests(/auth).
You have to get user information in /auth request too by session id.
(Or) Better you can use passport for authentication.
HOW? How do you "get user information in /auth request too by session id"?
Please ask for anything else you need to straighten me out.
I'm stumped. I have tried some dumb stuff already!
The variable is undefined in other routes if you don't log in first in the browser. Here is my test code:
var express = require('express');
var cors = require('cors');
app = express();
app.use(cors());
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'this is a test' }));
app.use(express.static(require('path').join(__dirname, 'public')));
app.get('/login', function(req, res) {
req.session.uid = 'user001';
res.send(req.session);
});
app.get('*', function(req, res) {
res.send(req.session);
});
app.listen(8080);
First visit http://localhost/login in the browser. Then visit other URLs(e.g., http://localhost/test) in this browser, the user id in the session is returned. So maybe there is something wrong in other parts of your code.
Test settings:
Ubuntu Desktop 13.10, 64 bit
Node 0.10.26
NPM 1.4.4
Express 3.4.8
cors 2.2.0