i'm trying to get passport to work with my node express server. I can login in with Facebook and find the correct user in my database; however, when I redirect req.user
is always undefined. Here is my server code:
var express = require('express'),
path = require('path'),
http = require('http'),
passport = require('passport'),
FacebookStrategy = require('passport-facebook').Strategy,
user = require('./routes/users');
var app = express();
passport.use(new FacebookStrategy({
clientID: "HIDDEN",
clientSecret: "HIDDEN",
callbackURL: "http://MYURL.com/auth/facebook/callback",
passReqToCallback: true
},
function(req, accessToken, refreshToken, profile, done) {
user.findOrCreate(profile, function(err, user) {
if (err) { return done(err); }
done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
user.findById(id, function(err, user) {
done(err, user);
});
});
app.configure(function () {
app.set('port', process.env.PORT || 3000);
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'foobar' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
});
app.get('/auth/user', function (req, res) {
console.log(req);
});
app.get('/auth/facebook', passport.authenticate('facebook'));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { successRedirect: '/',
failureRedirect: '/login' }));
http.createServer(app).listen(app.get('port'), function () {
console.log("Express server listening on port " + app.get('port'));
});
I go to /auth/facebook, it finds the correct user and redirects me to /. But then I go to /auth/user and req.user
is undefined and my sessions show this:
cookies: { 'connect.sid': 's:JFdQkihKQQyR4q70q7h2zWFt.VS+te0pT0z/Gtwg7w5B33naCvA/ckKMk60SFenObxUU' },
signedCookies: {},
url: '/auth/user',
method: 'GET',
sessionStore:
{ sessions:
{ '5sk3Txa2vs5sYhvtdYwGaUZx': '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"passport":{"user":"50c527c9c6cb41860b000001"}}',
'Au6m0hAj/3warKOGNSWw0yu2': '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"passport":{}}',
JFdQkihKQQyR4q70q7h2zWFt: '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"passport":{}}' },
generate: [Function],
_events: { disconnect: [Function], connect: [Function] } },
sessionID: 'JFdQkihKQQyR4q70q7h2zWFt',
Does it have something to do with my sessionID not matching the session where the passport user is set?
Update
So I determined that the sessionID not matching was because I'm running my code on c9.io and it actually has two URLs. When I use the correct URL and go to /auth/user my sessionID matches the session with passport user set and I can see in the log my deserializeUser finding the correct user object. However, req.user
is still undefined after this.
Trying to find user with id: 50c527c9c6cb41860b000001
{ sessions:
{ yoOUOxyXZ0SmutA0t5xUr6nI: '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"passport":{"user":"50c527c9c6cb41860b000001"}}',
goZpmK3y3tOfn660hRbz2hSa: '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"passport":{}}',
'O5Sz1GuZqUO8aOw4Vm/hriuC': '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"passport":{}}' },
generate: [Function],
_events: { disconnect: [Function], connect: [Function] } }
sessionID: yoOUOxyXZ0SmutA0t5xUr6nI
req.user: undefined
{ cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true },
passport: {} }
Update2
I figured out the problem. It was in my user.findByID function:
exports.findById = function(id, callback) {
console.log('Trying to find user with id: ' + id);
db.collection('users').findOne({'_id':id}, function(err, user) {
callback(err, user);
});
};
changed to:
exports.findById = function(id, callback) {
console.log('Trying to find user with id: ' + id);
db.collection('users').findOne({'_id':new BSON.ObjectID(id)}, function(err, user) {
callback(err, user);
});
};
app.get
or any other route. As you can define user route before passport middleware so that way in this route there will be no user data as well. (It is not specifically your case, but has very similar symptoms). – moka