【问题标题】:Passport token auth *without* database sessionPassport token auth *without* 数据​​库会话
【发布时间】:2016-02-24 11:34:12
【问题描述】:

我正在寻找一种方法来为 Passport.js 使用 Twitter 策略,而无需在数据库中使用会话集合/表。 这样做的原因是我们将所有数据保存在会话集合中,这些数据可能会变得非常大,并且每当用户发出请求时我们都会保存数据库往返,因为我们不必每次都去数据库来获取会话数据。

无论如何,我们应该能够使用令牌(JSON Web Token)来验证用户身份,正如这篇精彩的文章所描述的那样:

https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens

但我很困惑,为什么没有一种简单的方法可以用 Passport 做到这一点? (这篇文章在没有 Passport 的情况下做所有事情 - 但肯定 Passport 已经涵盖了这一点?)。

也许我想太多了,这样做的方法只是省略我在 Express 中使用数据库会话的调用,然后 Passport 已经足够聪明来处理 JWT?不知何故,我对此表示怀疑。

例如,在我的 Express 服务器中仅注释掉这段代码肯定是不够的:

//app.use(expressSession({
//    secret: 'arrete_x_paulette',
//    store: new MongoStore({mongooseConnection: mongoose.connection}),
//    saveUninitialized: true,
//    resave: true,
//    cookie: {
//        secure: false,
//        maxage: 6000000
//    },
//    proxy: false
//}));

//app.use(passport.session());

那么,使用 Passport 就够了吗?

为什么有人会使用存储在数据库中的会话而不是使用基于 JWT 的身份验证?

【问题讨论】:

  • 如果有人能回答这个问题,我将不胜感激。我也有同样的问题。
  • 想开始赏金还是应该冒险?
  • @ChaseIsley 认为我想通了,我认为您需要做的就是注释掉 MongoStore 部分或 expressSession 选项,然后它将只使用 cookie

标签: node.js express passport.js jwt express-jwt


【解决方案1】:

更新:更好的解决方案是完全禁用会话。

我认为通过将{ session: false } 传递给passport.authenticate 来删除用于express 的会话中间件并为护照禁用它应该可以工作,请参阅docs

这个想法是会话数据存储在令牌中,因此您根本不需要会话。 将其存储在内存中(如下所述)只会浪费内存。将它存储在客户端的 cookie 中也不好,因为客户端应该决定将令牌存储在哪里而不是服务器。


如果您只想将 express.js 会话保留在内存中,并且如果您使用标准 expressjs 的会话来处理会话,那么您只需删除 store: new MongoStore(...) 行:

app.use(expressSession({
    secret: 'arrete_x_paulette',
    saveUninitialized: true,
    resave: true,
    cookie: {
        secure: false,
        maxage: 6000000
    },
    proxy: false
}));

默认使用MemoryStore,参见documentation

【讨论】:

  • 是的,谢谢,实际上使用cookieSession比expressSession好,因为即使服务器重新启动它似乎也能保持会话。
  • @AlexMills 我认为 cookieSession 看起来很奇怪 - 它将服务器会话存储在客户端,但在 JWT 的情况下,客户端应自行决定将令牌存储在何处。这样,您最终可以在客户端上存储双令牌。第二个想法,更好的解决方案是按照您在问题中的建议完全删除 expressSession 中间件。你试过了吗?这个解决方案有什么问题?
  • @AlexMills 可能你需要做的也是disable passport.js sessions。由于会话数据在令牌内,因此无需在服务器上存储任何内容。
  • @AlexMills 还发现了一个app example,它似乎使用了完全没有会话的方法,也许它对你有用。
【解决方案2】:

@Boris Serebrov 的回答大部分是正确的。您可能希望设置 {session: false} 以便会话不存储在服务器本身的内存中,以及不将会话保存在数据库中。但这个故事可能还有更多内容。

人们使用持久内存存储的原因之一是因为这意味着如果服务器重新启动,会话不会丢失。但是,我们已经承诺基于 JWT 令牌的无状态身份验证。因此,如果它是无状态的,那么服务器重新启动又有什么关系呢?一旦服务器重新启动并运行,无论服务器的状态如何,相同的令牌都应该是有效的,对吧?

我发现,在我简短的讨论中,expressSession 将提供会话,如果服务器重新启动,将丢失。这可能促使人们首先使用 Mongo 和 Redis 使用持久会话!但你不需要这样做!我看不出有任何理由使用存储在数据库中的持久会话。您应该使用 JWT 和无状态身份验证...所以替代方案似乎是 cookieSession,Express 的另一个模块。

如果你像这样使用 cookieSession:

app.use(cookieSession({
    name: 'some-cookie',
    keys: ['key1', 'key2']
}));

那么即使您的服务器重新启动,“会话”仍然存在。这适用于您当前的 Passport 配置,只要您删除在 MongoStore 等中存储会话的调用。

https://github.com/expressjs/cookie-session

如果我错了或忽略了什么,请纠正我。

【讨论】:

    猜你喜欢
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 2019-10-02
    • 2014-03-26
    • 2021-06-21
    • 2013-03-11
    • 2013-03-28
    相关资源
    最近更新 更多