首页 > 解决方案 > 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);
  });
}

标签: node.jsexpresspassport.js

解决方案


风滚草!

所以事实证明它工作正常 - 问题只是 Chrome 跨标签重复使用它的会话。我在这个问题的答案中发现了一个有用的评论。一个从 Chrome 登录,另一个从 IE 登录工作正常,没有冲突。

Node + Passport - 多个用户


推荐阅读