After the initial successful login from Facebook and login redirection callback using passport-facebook 1.0.3 and express 4.6.1,req.session.passport and req.user contains the value set during the serialize call(which i get from the stragegy) , but on subsequent visits to different routes on the site the req.session.passport and req.user is blank , and req.isAuthenticated() returns false , so after the initial successful login from FB the ensureAuthentication method on all other routes fails . I'm not using a cluster setup , so i believe the memory store is enough to handle this , the express configuration looks fine(i mean the order) , here is my express configuration
configExpressApp.set('views', './views');
configExpressApp.set('view engine', 'jade');
configExpressApp.use(morgan('dev'));
configExpressApp.use(cookieParser());
configExpressApp.use(bodyParser.urlencoded({
extended: true,
}));
configExpressApp.use(bodyParser.json());
configExpressApp.use(expressSession({
secret:'MyExpressSecret',
saveUninitialized: true,
resave: true
}));
configExpressApp.use(passport.initialize());
configExpressApp.use(passport.session());
configExpressApp.use(methodOverride());
configExpressApp.use(express.static('./public'));
Here is the req.session object on the initial successfull login and redirection ,The req.user contains the same data as the req.session.passport.user
{ cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true },
passport:
{ user:
{ _id: 53ce23e3121421f229a438f8,
info: false,
loginType: 'fb',
fbId: 'MyId',
name: 'Karthic Rao',
email: '[email protected]'
}
}
}
this is the information i associated earlier with the done() callback inside the strategy and also inside the serialization call . After the successfull login and callback, i use res.redirect to redirect the user to a different route , but the requests coming from that route contains the sessionID (so i dont think its the issue with the session store), but the req.user field doesnt exist(may be because passport.initialize() and passport.session() middlewares dont find the request to be authenticated) and the req.session.passport field is empty , here are the details from the console.log of the req object .
sessionID: 'I9R1c3PIYgDW5OpWbNT7qb02Hn4lOeAB',
session:
{ cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true },
passport: {} },
Here is my deserialize method
passport.deserializeUser(function(user, done) {
console.log('deserialize loginType facebook');
db.collection("users").findOne({
fbId: user.id
}, function(err, docs) {
console.log(docs);
done(err, docs);
});
});
Here is my serialize method
passport.serializeUser(function (user, done) {
console.log(user);
done(null, user);
});
This is creating a great hindrance to my development , how can i sort this out ??
Well, if you could add the code where you use your strategy (it should be in the middleware), that would give us a complete view of the problem, because we need to know what object is sent to serializeUser
.
(Very) basically, when a user tries to authenticate, things happen that way :
req.login
to store some info about
the user in sessionserializeUser
is called and effectively store the data you
specified in session.BUT from the code you posted, I suspect that in your deserializeUser
, user.id is undefined, because the user
object that is stored in session uses an ID field called _id and not id.
If you change
db.collection("users").findOne({
fbId: user.id
to
db.collection("users").findOne({
fbId: user._id
db.collection("users").findById(user._id, [fields],[options],[callback]);
I think it should work.
EDIT : I edited my answer based on @BrandonZacharie's remark, which pointed out an error in my code.