passportJS serializeUser 和 deserializeUser 从未调用过
Posted
技术标签:
【中文标题】passportJS serializeUser 和 deserializeUser 从未调用过【英文标题】:passportJS serializeUser and deserializeUser never called 【发布时间】:2016-03-24 10:15:24 【问题描述】:我想弄清楚我在这里做错了什么。在查看文档(遗憾的是已过时)并搜索网络后,我相信我已经正确配置了护照的所有内容,但由于某种原因,serializeUser 和 deserializeUser 都没有被调用,这导致 req.user 永远不会被设置。
好的,这是我的根 server.js 文件(摘要)
/**
* Module dependencies
*/
var express = require('express'),
app = module.exports = express(),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
env = process.env.NODE_ENV || 'development',
errorHandler = require('errorhandler'),
http = require('http'),
methodOverride = require('method-override'),
morgan = require('morgan'),
passport = require('passport'),
path = require('path'),
routes = require('./server/routes/index'),
secret = process.env.SESSION_SECRET,
session = require('express-session'),
FileStore = require('session-file-store')(session);
/**
* Configuration
*/
// all environments
app.set('http-port', process.env.PORT || 3000);
app.set('views', __dirname + '/public');
app.engine('.html', require('ejs').renderFile);
app.use(morgan('dev'));
app.use(methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser(secret));
app.use(bodyParser.urlencoded( extended: true ));
app.use(bodyParser.json());
// development enviornment only
if (env === 'development')
app.use(session(
cookie: maxAge: (60 * 60 * 10) , // User session will expire after 60 minutes.
resave: false,
saveUninitialized: false,
secret: secret,
));
app.use(errorHandler());
app.use(passport.initialize());
app.use(passport.session());
/**
* Routes
*/
routes.SESSION_SECRET = secret; // Set env var for the router;
app.use('/', routes); // Handle defined routes
app.get('/', routes.index); // Serve index
app.get('*', routes.index); // Redirect all others to the index (HTML5 history)
/**
* Start Server
*/
var httpServer = http.createServer(app);
httpServer.listen(app.get('http-port'), function ()
console.log('Express http server listening on port ' + app.get('http-port'));
);
你会注意到上面的这一行:
routes = require('./server/routes/index'),
这是路由文件(摘要):
var express = require('express');
var router = express.Router();
var auth = require('./modules/auth');
// AUTH ROUTES
router.post('/login', auth.login); // Log a local user into the application using passport
router.post('/ldap-login', auth.ldapLogin); // Log a LDAP user into the application using passport
router.get('/logout', auth.logout); // Log the current user out of the system
router.get('/isLoggedIn', auth.isLoggedIn); // Check is the user is logged in
router.post('/updatePassword', auth.updatePassword); // Updates a users password
你会再次注意到这个参考:
var auth = require('./modules/auth');
这是 auth 模块(摘要)。
'use strict'
var passport = require('passport');
var secret = process.env.SESSION_SECRET;
var crypto = require('../../crypto');
var models = require('../../models');
var User = models.User;
require('../../passport');
// Log a local user into the application using passport
exports.login = function(req, res, next)
passport.authenticate('local', function(err, user, info)
if(err) return next(err);
if(user)
User.find(
where:
email: user.email
)
.then(function(currentUser)
if(currentUser)
currentUser.updateAttributes(
last_login: new Date()
);
);
user.email = crypto.decrypt(user.email);
user.first_name = crypto.decrypt(user.first_name);
user.last_name = crypto.decrypt(user.last_name);
return res.json( token: user.generateJWT(secret) );
else
return res.status(401).json(info);
)(req, res, next);
在该文件中,我引用了我的护照配置,其中包含我希望使用的功能。
require('../../passport');
这是那里引用的护照配置(摘要)。
(function()
var models = require('./models');
var User = models.User;
/**
* Passport authentication
*/
var passport = require('passport');
// Passport Local Strategy
var locStrategy = require('passport-local').Strategy;
passport.use(new locStrategy(
usernameField: 'username'
,
function(username, password, done)
User.find(
where:
username: username
)
.then(function(user)
if(!user)
console.log('No such user found');
return done(null, false);
user.verifyPassword(password, function(err, isMatch)
if(err)
console.log('Error checking password. Error: ' + err);
return done(err);
else if(!isMatch)
// Password did not match
console.log('Passwords did not match');
return done(null, false);
else
// Success
console.log('User logged in');
return done(null, user);
);
)
.catch(function(err)
console.log('Error logging user in. Message: ' + err);
return done(err);
);
));
passport.serializeUser(function(user, done)
console.log('serializeUser'); // I expect this to be logged
done(null, user);
);
passport.deserializeUser(function(user, done)
console.log('deserializeUser'); // I expect this to be logged
done(null, user);
);
exports.isAuthenticated = passport.authenticate(['local', 'ldapauth']);
)();
您会注意到那里对 User 模型的引用,但由于它工作正常,我不会包含任何代码。
我不确定这里有什么问题阻止我点击上面的 passport.serializeUser 和 passport.deserializeUser 方法。我想我可能需要在 server.js 根目录中包含这些方法,所以我尝试在 session() 配置上方和 passport.session() 调用之后移动这些方法,但没有任何更改有任何效果。
【问题讨论】:
【参考方案1】:找到问题了,希望能帮到别人。
要调用 deserializeUser,您需要在 passport.authenticate() 解析后手动调用 req.login()。我没有这样做,因为在 Passport 文档中它说:
"Note: passport.authenticate() middleware invokes req.login() automatically."
至少在我看来,当您调用 passport.authenticate() 时,passport 应该调用 login,然后自动反序列化用户,但这是不正确的。
这是我的身份验证模块中的更新代码:
exports.login = function(req, res, next)
passport.authenticate('local', function(err, user, info)
if(err) return next(err);
if(user)
User.find(
where:
email: user.email
)
.then(function(currentUser)
if(currentUser)
currentUser.updateAttributes(
last_login: new Date()
)
);
user.email = crypto.decrypt(user.email);
user.first_name = crypto.decrypt(user.first_name);
user.last_name = crypto.decrypt(user.last_name);
req.login(user, function(err) // I added req.login() here and now deserializeUser is being called and req.user is being set correctly.
if(err)
return res.status(401).json(err);
else
return res.json( token: user.generateJWT(secret) );
);
else
return res.status(401).json(info);
)(req, res, next);
【讨论】:
以上是关于passportJS serializeUser 和 deserializeUser 从未调用过的主要内容,如果未能解决你的问题,请参考以下文章
PassportJS:如何在我的视图中获取 req.user
护照身份验证不起作用。从未调用过的 Passport.serializeUser 和 passport.deserializeUser 会被调用
javascript PassportJS身份验证设置#passportjs #cookiesession #nodejs