【问题标题】:express-session cannot destroy sessionexpress-session 不能销毁会话
【发布时间】:2018-10-10 13:10:39
【问题描述】:

我初始化express-session:

const session = require('express-session')
const MongoStore = require('connect-mongo')(session);
//use sessions for tracking logins
app.use(session({
  secret: 'secret',
  resave: true,
  saveUninitialized: false,
  store: new MongoStore({
    mongooseConnection: mongoose.connection
  })
}));

我用于检查身份验证的中间件:

function requiresLogin(req, res, next) {
  if (req.session && req.session.userId) {
        console.log('Session OK ' + JSON.stringify(req.session) );
    return next();
  } else {
    var err = new Error('You must be logged in to view this page.');
    err.status = 401;
    return next(err);
  }
}

我的logout 端点:

// GET /logout
exports.logout = function(req, res, next) {
  if (req.session) {
    // delete session object
    req.session.destroy(function(err) {
      if(err) {
        return next(err);
      } else {
                req.session = null;
                console.log("logout successful");
        return res.redirect('/');
      }
    });
  }
};

我的测试:

我向位于requiresLogin 中间件后面的test 端点提交了一个请求,我得到了(如预期的那样):

Error: You must be logged in to view this page.

我向我的 login 端点提交请求,我得到一个 cookie:

set-cookie: connect.sid=s%3A0doMoVwGPkcVUgar3uP5WR36b7k9_v27.O2B8vl35TQLiet3WltP2UAH3iuaeif3%2BPDActkTBYUw; Path=/; HttpOnly

我在test 端点上再次使用此 cookie:

Session OK {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"userId":"5ae6ddee1239c157ec36c06c"}

我执行/logout,为此我得到了

logout successful

之后,我使用我相信我刚刚销毁的 cookie 再次尝试我的 test 端点:

Session OK {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"userId":"5ae6ddee1239c157ec36c06c"}

destroy成功后数据库中的会话保持不变。

为什么我在销毁会话后可以使用我的会话身份验证 cookie?

编辑

应该删除问题。我在执行/logout 时使用了错误的 Cookie。愚蠢的错误,我的错......

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    默认情况下,express-sesssion 中间件将检查现有的会话 cookie,如果不存在,它将在中间件运行的任何请求上创建一个新的 cookie 和一个新的会话对象。

    要支持登录功能,您必须实际实现某种形式的身份验证,并且如果登录凭据本身未验证,则不要创建新的会话 cookie 和会话对象。或者,您可以在会话对象中添加一个标志,指示该会话的登录是否已经过验证,然后检查会话是否存在以及是否设置了已验证的标志。

    您显示的代码位看起来就像每个传入连接都只是创建一个新的会话对象(如果一个尚不存在),并且您所有的验证代码所做的都是检查会话对象是否存在,它总是会因为一旦你摆脱它,下一个传入的请求将再次运行中间件并创建一个新的会话 cookie 和对象。

    有关示例,请参阅 how to implement login auth in node.js

    【讨论】:

    • req.session.userId 检查 userId 是否存在。这不会由中间件自动设置...我确实有身份验证,但我跳过了一些部分。感谢您的回复。事实证明没有任何问题......(我编辑了问题)
    猜你喜欢
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 2011-11-06
    • 1970-01-01
    相关资源
    最近更新 更多