node.js - Passport + Express - 用户会话冲突
问题描述
我有一个带有 Passport Local 身份验证的简单 Node+Express 应用程序,它工作得几乎完美(提供了正确的页面,登录/注销工作等)。
但一个问题是,如果第二个用户登录,该会话“接管”第一个用户的会话,突然第一个用户现在作为第二个用户登录!
这几乎可以肯定是中间件顺序的问题,但我找不到它——我对 Passport 和 Express 还很陌生。代码大量取自文档和示例,但我可能把顺序搞砸了。
我已按照此答案中的顺序进行操作,但仍然无法正常工作。谁能建议我可能在哪里混淆?
主服务器:
var express = require('express');
var passport = require('passport');
var Strategy = require('passport-local').Strategy;
var url = require('url');
var db = require('./db');
// Configure the local strategy for use by Passport.
passport.use(new Strategy(
function(username, password, cb) {
db.users.findByUsername(username, function(err, user) {
if (err) { return cb(err); }
if (!user) { return cb(null, false); }
if (user.password != password) { return cb(null, false); }
return cb(null, user);
});
}));
// Configure Passport authenticated session persistence.
passport.serializeUser(function(user, cb) {
console.log('DEBUG: serializeUser called ' + user.id);
cb(null, user.id);
});
passport.deserializeUser(function(id, cb) {
console.log('DEBUG: deserializeUser called ' + id);
db.users.findById(id, function (err, user) {
if (err) { return cb(err); }
cb(null, user);
});
});
// Create a new Express application.
// Use application-level middleware for common functionality (Order is important!)
// Initialize Passport and restore authentication state, if any, from the session.
var app = express();
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({ secret: 'qwerty', resave: false, saveUninitialized: false })); // Step 2.
app.use(passport.initialize());
app.use(passport.session());
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login.html' }),
function(req, res) {
console.log('Logged In: ' + req.user.username);
res.redirect('/');
});
app.get('/logout', function(req, res){
if (req.user != null) {
console.log('Logged Out: ' + req.user.username);
req.logout();
} else {
console.log('Warning: null user logging out');
}
res.redirect('/login.html');
});
app.get('/user', function(req, res){
if (req.user != null) {
res.send(req.user.displayName);
} else {
res.send('ERROR: No current user?');
}
});
function isAuthenticated(req, res, next) {
if (req.user) { // User is logged in
return next();
}
if (req.url.startsWith('/login')) { // Allow login through to avoid infinite loop
return next();
}
res.redirect('/login.html');
}
app.use('/', isAuthenticated, express.static('/public/'));
db/users.js 文件:
var records = [
{ id: 1, username: 'jill', password: 'birthday', displayName: 'Jill'}
{ id: 2, username: 'jack', password: 'hello', displayName: 'Jack'}
];
exports.findById = function(id, cb) {
process.nextTick(function() {
var idx = id - 1;
if (records[idx]) {
cb(null, records[idx]);
} else {
cb(new Error('User ' + id + ' does not exist'));
}
});
}
exports.findByUsername = function(username, cb) {
process.nextTick(function() {
for (var i = 0, len = records.length; i < len; i++) {
var record = records[i];
if (record.username === username) {
return cb(null, record);
}
}
return cb(null, null);
});
}
解决方案
风滚草!
所以事实证明它工作正常 - 问题只是 Chrome 跨标签重复使用它的会话。我在这个问题的答案中发现了一个有用的评论。一个从 Chrome 登录,另一个从 IE 登录工作正常,没有冲突。
推荐阅读
- javascript - 如何将 xlxs 文件制作为 blob
- python - 如何仅使用“公平硬币”生成具有 1/3 成功概率的有偏硬币
- powershell - 不确定 Get-ChildItem 结果格式
- ios - viewWillTransition 没有被称为 swift 4
- node.js - 发送消息时感到困惑。对话框。添加()?session.send()?context.sendActivity()?
- pimcore - 如何通过 Pimcore 的网络服务创建用户
- java - 无法使用我的 docker 映像访问 Spring Boot
- php - 使用另一个数组按子数组键对多维数组进行自定义排序
- android - 使用 Intent 构建、安装 APK
- python - 如何在 Django 功能测试中触发空值验证?