PassportJS反序列化用户从未调用过

我有Passport安装程序来validation存储在mongodb中的用户。 似乎工作正常:身份validation成功/失败适当和会话variables设置。 但是,获得护照检查会话失败。 一些东西似乎是相当错误的,我添加到deserializeUsercallback的console.log语句永远不会看到白天的光芒。 我认为我的问题是关系到deserializeUser永远不会被调用。 任何人都可以诊断我的失误?

 // Passport configuration passport.serializeUser(function(user, cb){ cb(null, user.id) }); passport.deserializeUser(function(uid, cb){ console.log("Trying to deserialize user: "+uid); User.findById(uid, function(err, user){ cb(err, user); }); }); // auth strategy function passport.use(new LocalStrategy({usernameField: 'email'}, function(email, pass, done){ User.findOne({email: email}, function (err, user) { if (err) return done(err); if (!user) return done(null, false, {message: "Couldn't find user"}); var crypted = bcrypt.hashSync(pass, user.salt); if(user.hashpass != crypted) return done(null, false, {message: "Bad password"}); return done(null, user); }); } )); passport.CreateSession = function (req, res, next) { passport.authenticate('local', function(err, user, info){ if(err || !user) return res.json({status: "Failure: "+err}); req.logIn(user, function (err){ if(err) return res.json({status: "Failure: "+err}); return res.json({status: "Authenticated"}); }); })(req, res, next); }; 

在app.js中包含以下内容:

 app.post('/session', passport.CreateSession); // restify better app.del('/session', passport.DestroySession); app.get('/images', passport.CheckSession, routes.images); 

对于有这个问题的其他人,请看看这个:

 app.use(session({ secret: 'something', cookie: { secure: true }})); 

如果cookie.secure设置为true,而您没有使用SSL(即https协议),那么带有会话ID的cookie不会返回给浏览器,并且一切都会自动失败。 删除这个标志解决了我的问题 – 花了几个小时才明白!

如果您在使用护照进行authenticate时使用authenticatecallback,则需要手动login用户。 它不会被要求你。

 passport.authenticate('local', function (err, user) { req.logIn(user, function (err) { // <-- Log user in return res.redirect('/'); }); })(req, res); 

use() ' passport.session()中间件? 像这个例子一样:

https://github.com/jaredhanson/passport-local/blob/v1.0.0/examples/login/app.js#L91

这就是恢复会话,并调用deserializeUser ,所以这听起来像可能会丢失。

我一整天都在打同样的问题。 我有一个自定义callback设置做授权(如http://passportjs.org/guide/authenticate/底部)&#x3002; 它看起来像Passport预处理所有的请求对象之前,他们甚至击中了其他中间件(根据我写的一些日志语句)。 作为预处理的一部分,它将反序列化的用户信息放入request.user对象中。 不幸的是,passport.authenticate('local',callback)的默认行为似乎是忽略任何会话或cookie数据,而是假定用户名和密码正在请求对象中发送。 我所做的解决这个问题的方法是首先检查request.user对象,如果它存在,这意味着Passport已经完成预处理,然后我可以直接调用login。 这里是我的授权function,我用它来代替passport.authenticate('local'):

 function doAuth(request, response, next) { if (request.user) { request.logIn(request.user, function (err) { if (err) { console.log(err); response.status(500).json({message: "Login failed. Auth worked. Nonsense"}); return; } console.log("doAuth: Everything worked."); next(); }); return; } passport.authenticate('local', function(err, user, info) { if (err) { response.status(500).json({message: "Boo Passport!"}); return; //go no further //until I figure out what errors can get thrown } console.log("Authentication failed. Here is my error:"); console.log(err); console.log("Here is my info:"); console.log(info); response.status(500).json({message: "Authentication failed."}); return; } request.logIn(user, function(err) { if (err) { console.log("Login failed. This is the error message:"); console.log(err); response.status(500).json({message:"Login failed."}); return; } console.log("doAuth: Everything worked. I don't believe it."); next(); }); })(request, response, next); } 

今天我面临同样的问题,在我的情况下,原因是客户端如何进行API调用。 下面的方法帮助我解决了这个问题:

 const doFetch(url, method = 'GET', body) { const headers = new Headers(); headers.append('Content-Type', 'application/json'); headers.append('Accept', 'application/json'); headers.append('Cache', 'no-cache'); const params = { method, headers, credentials: 'include' // The cookie must be sent! } if(body) { params.body = body; } return fetch(url, params); } 

在此之后, deserializeUser开始被正确调用。

 passport.serializeUser( function(user, done){ done(null, user.id); }); passport.deserializeUser( function(id, done){ User.findById(id, function(err, user){ if(err){ done(err); } done(null, user); }); }); **> try this one** 

确保代码行app.use(express.static(path.join(__dirname, 'public'))); 停留在app.use(require('express-session')