Express.js / Passport应用程序为每个请求创build新的会话,尽pipe会话ID在请求标头中

之前没有注意到这一点,因为对于客户端 – 服务器通信,通过XHR(至今)还没有需要validation的事情。 在实现一些集成testing时,我正在创buildrealy请求node-xmlhttprequest到应用程序的一个实例。 用户在第一个请求中被authentication,理论上用户的唯一标识符和一些其他相关信息被存储在会话中(正如我所说的,这对于真正的客户端来说很好,他们不需要通过XHR来确认他们的身份)。 出于某种原因,即使随后的请求正在使用完全相同的会话ID触发,我无法在后续请求中检索会话,因此无法看到用户已通过身份validation,这导致失败的testing,其中预期的行为不会发生,HTTP 401 UNAUTHORIZED正在填满terminal。

我见过几个这样的问题,但是“同一个会话ID”似乎并不存在于其中。

我是否需要手动添加Set-Cookie头到所有的XHR请求? 太糟糕了,还有更好的办法!

所以人们喜欢源代码,这里有一些来自testing,发出这些请求:

// Ensure logged in before sending request, to verify that authorized // users encounter the expected behaviour. jQuery.post(domain+'/login', {email:'test@express.app', password:'12345678'}, function(data,x,y){ data.should.equal("true") jQuery.ajax({url:domain+'/event', type:"POST", name: "TestEvent", location: "TestVille", startDate: new Date('2013-09-01'), startTime: '6:45 pm', description: "Test Event #1", success: state.success, error: state.error, completed: state.completed }) }) 

login发生时,用户ID被写入会话(`req.logIn()应该这样做,它不报告任何失败),用户ID的序列化不会报告任何失败,我很困惑,为什么后续使用相同会话ID的请求无法find序列化的用户ID。

我一般不参与networking开发,所以这对某些人来说可能是显而易见的,但是我一直在寻找一个答案,根本找不到。 我会很感激任何指针,并且很乐意提供尽可能多的代码,以说明问题所在。

另外几点可能相关的代码:

用户ID的序列化/反序列化(目前以最简单的方式实现 – 这在初始化passport和passpot.session()之后初始化中间件的很早,对于非XHR请求来说非常合适)

 // Serialize user for passport session-store // Currently only serializing 'user_id' passport.serializeUser(function(user, done) { done(null, user._id) }) // Deserialize user from session-store to provide // access to the User instance passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user) }) }) 

通过本地策略validation用户:

 passport.use(new LocalStrategy({ usernameField: "email", passwordField: "password", passReqToCallback: true, failureFlash: true }, function(req, email, password, done) { User.findByEmail(email, function(err, user) { if(user) { if(err) console.log(err) if(user instanceof UserLocal) { user.verifyPassword(password, function(err, match) { if(err) console.log(err) if(!match) { return done(err, false, "Username or password is incorrect.") } return done(null, user) }) } else { var msg = "Account registered under " + user.providerName() + ", please login using " + user.providerName() return done(err, false, msg) } } else { return done(err, false, "Username or password is incorrect.") } }) }) 

最后是写入会话的请求:

 function loginHelper(req, res, next) { passport.authenticate('local', { failureFlash:true, failureRedirect: false, successRedirect: false }, function(err, user, info) { req.logIn(user, function(err) { if(!err) err = {} if(req.xhr) { console.log(req.session) res.status(200).end(err.message || "true") } else { if(err.message) req.flash('error', err.message) else res.redirect('/') } }) })(req, res, next) } 

我知道有一些奇怪的事情,例如无论login状态如何都发送200的状态,但是我可以确认序列化的用户ID是在初始loginXHR请求中写入会话的,并且在随后的XHR请求中没有反序列化。

我相信我刚才提到,在这方面我相对缺乏经验,可以大大提高。 任何的援助将不胜感激,提前感谢。

首先,这对我有帮助

 app.use(express.static(__dirname + '/public', { maxAge: oneDay })); 

并更新函数来不触发数据库

  passport.serializeUser( (user, done) => { var sessionUser = { id: user.dataValues.id, fio: user.dataValues.fio, email: user.dataValues.localemail, role: user.dataValues.role, login: user.dataValues.login, position: user.dataValues.position } done(null, sessionUser) }) passport.deserializeUser( (sessionUser, done) => { // The sessionUser object is different from the user mongoose collection // it's actually req.session.passport.user and comes from the session collection done(null, sessionUser) }) 

https://www.airpair.com/express/posts/expressjs-and-passportjs-sessions-deep-dive