【问题标题】:Express.js Session storage persistence issueExpress.js 会话存储持久性问题
【发布时间】:2020-06-11 18:37:01
【问题描述】:

我在使用 mongoDB 和护照的会话存储方面遇到了一个非常奇怪的问题。

当用户登录时,会话被创建并按预期传递给 mongo 以及护照 ID。

{
    "_id" : "GEEFIDhiMehdjPvtxRmPy_Kuls2IdVsx",
    "expires" : ISODate("2020-06-10T03:09:30.396Z"),
    "session" : "{\"cookie\":{\"originalMaxAge\":28800000,\"expires\":\"2020-06-10T03:09:29.358Z\",\"httpOnly\":true,\"path\":\"/\"},\"passport\":{\"user\":\"ebf7d73d-f3f2-4f96-8123-3f0f262ffff6\"}}"
}

但是,当快速服务器重新启动时,当用户选择需要身份验证的路由(通过调用 isAuth 函数)时,护照会将用户从会话存储中清除。这意味着用户需要在服务器重启后登录。

{
    "_id" : "GEEFIDhiMehdjPvtxRmPy_Kuls2IdVsx",
    "expires" : ISODate("2020-06-10T03:11:54.464Z"),
    "session" : "{\"cookie\":{\"originalMaxAge\":28800000,\"expires\":\"2020-06-10T03:11:54.464Z\",\"httpOnly\":true,\"path\":\"/\"},\"passport\":{}}"
}

我的身份验证代码是非常标准的东西,我哪里错了?我正在使用 azure-ad passport 策略。

const passport = require('passport');
const OIDCStrategy = require('passport-azure-ad').OIDCStrategy;
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const config = require('../config');

const store = new MongoStore({
  url: config.databaseUri,
});

// Usual passport code here findbyoid, ensureAuthenticated etc

function setupPassport(app) {
  app.use(
    session({
      secret: 'somepassword',
      resave: true,
      cookie: {
        maxAge: 8 * 60 * 60 * 1000,
      },
      saveUninitialized: true,
      store: store,
    })
  );
  app.use(passport.initialize());
  app.use(passport.session());
}

【问题讨论】:

  • 我会寻找的一些东西是确保会话在 Mongo 中——这意味着使用一些外部工具来确保数据在那里。然后,如果是这样,请在重新启动后再次检查。这可能有助于缩小问题的范围。如果您的秘密永远不会改变(即它不是生成秘密的某种加密功能),那么我认为没有理由它不会获取会话,除非它一开始就没有到达那里。还测试具有更长 maxAge 的东西。我已经看到服务器时间不同导致奇怪的过期问题的问题。
  • @cyberwombat 前 2 个代码 sn-ps 来自 mongo 数据库 bud,会话被挑衅地存储,似乎会话在重新启动后永远不会被重新收集,而是在用户被覆盖时被覆盖登录。

标签: node.js mongodb express session passport.js


【解决方案1】:

我实际上并没有在会话中存储正确的用户信息,甚至没有在会话中查找用户信息。相反,我将用户存储在本地数组中,并使用 deserializeUser 函数查找他们的 oid。解决方案是用下面的代码替换它。

passport.serializeUser(function (user, done) {
  done(null, user);
});

passport.deserializeUser(async (user, done) => {
  done(null, user);
});

这样,用户对象被存储在会话数据库中,然后在用户检查身份验证时重新收集。

【讨论】:

    猜你喜欢
    • 2013-05-10
    • 2015-12-18
    • 2019-03-16
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 2016-08-07
    相关资源
    最近更新 更多