req.session.passport和req.user空白,req.isAuthenticated在初次成功login后使用passport-facebook返回false

在Facebook上初次成功login并使用passport-facebook 1.0.3和express 4.6.1进行loginredirectcallback之后,req.session.passport和req.user包含serialize调用期间设置的值(我从stragegy获得),但在后续访问站点上的不同路由时,req.session.passport和req.user为空,req.isAuthenticated()返回false,因此在从FB初始成功login后,所有其他路由上的ensureAuthentication方法失败。 我没有使用集群设置,所以我相信内存存储就足够处理这个,快速configuration看起来很好(我的意思是顺序),这里是我的快速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')); 

这是req.session对象初始的成功login和redirect,req.user包含与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: 'kartronics85@yahoo.com' } } } 

这是我先前在策略内部与done()callback关联的信息,也是序列化调用中的信息。 成功login和callback后,我使用res.redirectredirect用户到不同的路线,但来自该路线的请求包含sessionID(所以我不认为它与会议存储问题),但req.user字段不存在(可能是因为passport.initialize()和passport.session()中间件不会find请求进行身份validation),并且req.session.passport字段为空,以下是来自请求的console.log的详细信息对象。

 sessionID: 'I9R1c3PIYgDW5OpWbNT7qb02Hn4lOeAB', session: { cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true }, passport: {} }, 

这是我反序列化的方法

 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); }); }); 

这是我的序列化方法

 passport.serializeUser(function (user, done) { console.log(user); done(null, user); }); 

这是对我的发展造成很大的阻碍,我怎么能解决这个问题呢?

那么,如果你可以在你使用策略的地方添加代码(它应该在中间件中),那么这将给我们一个完整的问题视图,因为我们需要知道什么对象被发送到serializeUser

(非常)基本上,当用户尝试authentication时,事情就是这样发生的:

  • 护照尝试对Facebook服务器进行身份validation
  • 如果成功,则使用包含用户详细信息的对象调用callback函数(或successRedirect)
  • 然后,Passport打电话给req.login在会话中存储关于用户的一些信息
  • 然后调用serializeUser并有效地存储在会话中指定的数据。

但是从你发布的代码中,我怀疑在你的deserializeUseruser.id是未定义的,因为存储在会话中的user对象使用一个名为_id而不是id的ID字段。

如果你改变

  db.collection("users").findOne({ fbId: user.id 

 db.collection("users").findOne({ fbId: user._id 

 db.collection("users").findById(user._id, [fields],[options],[callback]); 

我认为它应该工作。

编辑 :我编辑我的答案根据@ BrandonZacharie的评论,指出我的代码中的错误。