Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass user info in routes from Passport strategies

I am trying to authenticate user using passportjs using express.

Passport.js looks like this.

var USER_INFO = {};
var FB_CALLBACK = 'http://localhost:3000/auth/facebook/callback';
module.exports = function(passport) {
	passport.use(new FacebookStrategy({
		clientID: FB_CLIENT_ID,
		clientSecret: FB_CLIENT_SECRET,
		callbackURL: FB_CALLBACK
	}, 
	function(accessToken, refreshToken, profile, done) {
		process.nextTick(function() {
			USER_INFO.id = profile.id;
		});
	}));
}
var express = require('express'); // call express
var app = express(); // define our app using express
var router = express.Router(); // get an instance of the express Route
var passport = require('passport');
USER_INFO = {};
require('./config/passport')(passport);
app.get('/auth/facebook', passport.authenticate('facebook'));

app.get('/auth/facebook/callback', passport.authenticate('facebook', {
    successRedirect : '/fb',
    failureRedirect : '/error'
}));

app.get('/fb', function (req, res) {
    res.json(USER_INFO);
}); 

I want all the information extracted in res.json(user_info). But it is coming as empty. What I am missing here. What is the best method to save user basic info of user to keep him logged in.

like image 931
ghost... Avatar asked Jun 12 '15 06:06

ghost...


People also ask

What are passport strategies?

Passport's local strategy is a Node. js module that allows you to implement a username/password authentication mechanism. You'll need to install it like any other module and configure it to use your User Mongoose model.

How do I pass additional parameters to passport authenticate?

You can use the request itself to transfer some additional parameters from and to the strategy function. In the following example the two parameters _toParam and _fromParam are used for this concern. app. get('/auth/facebook/:appId', function(req,res,next){ req.

Can passport use multiple strategies?

Passport's middleware is built in a way that allows you to use multiple strategies in one passport.

What does passport authenticate () do?

In this route, passport. authenticate() is middleware which will authenticate the request. By default, when authentication succeeds, the req. user property is set to the authenticated user, a login session is established, and the next function in the stack is called.


2 Answers

Firstly, you should not store USER_INFO = {} outside the scope of your current request. If two separate users make a request then they'll get the same object.

You should at least store them in a way you can retrieve them separately

var USERS = {};
...
module.exports...
passport.use...
...

function(accessToken, refreshToken, profile, done) {
    USERS[profile.id] = profile;
    done(null, profile);
}));

Now if two separate users make a request they'll have their info separately stored within USERS

{
    1234: {id: 1234, name: FOO},
    6789: {id: 6789, name: BAR},
}

And done(null, profile) would serialize that user. If you haven't defined your serialize/deserialize functions you should do so like this:

passport.serializeUser(function (user, done) {
    done(null, user.id);
});
passport.deserializeUser(function (id, done) {
    var user = USERS[id];
    done(null, user);
});

Now your users will be available within their respective request contexts as req.user

So you just need to do:

app.get('/fb', function (req, res) {
    res.json(req.user);
}); 
like image 192
laggingreflex Avatar answered Oct 19 '22 08:10

laggingreflex


You forgot call done() in process.nextTick().

var FB_CALLBACK = 'http://localhost:3000/auth/facebook/callback';
module.exports = function(passport) {
    passport.use(new FacebookStrategy({
        clientID: FB_CLIENT_ID,
        clientSecret: FB_CLIENT_SECRET,
        callbackURL: FB_CALLBACK
    }, 
    function(accessToken, refreshToken, profile, done) {
        process.nextTick(function() {
            var USER_INFO = {};
            USER_INFO.id = profile.id;
            done(USER_INFO)
        });
    }));
}

You can pass any object to done(), it will become req.user later in your route. In your case, the USER_INFO which you want to response is req.user

app.get('/fb', function (req, res) {
    res.json(req.user);
}); 
like image 40
Kiet Thanh Vo Avatar answered Oct 19 '22 08:10

Kiet Thanh Vo