通过令牌进行身份验证,如果令牌失败,则通过会话进行身份验证,使用 Passport?

Posted

技术标签:

【中文标题】通过令牌进行身份验证,如果令牌失败,则通过会话进行身份验证,使用 Passport?【英文标题】:Authenticate by Token, then by Session if Token fails, using Passport? 【发布时间】:2014-10-30 13:44:00 【问题描述】:

我正在努力将具有 NodeJS + Express 后端的现有 Web 应用程序调整为 PhoneGap / Steroids 应用程序。目前,Web 应用程序的身份验证由 Passport (http://passportjs.org/) 使用会话处理。

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

在浏览器中效果很好。不幸的是,会话 cookie 似乎在 PhoneGap 中不起作用。所以发送到服务器的请求只会被拒绝。

PhoneGap 的推荐解决方案是使用令牌策略,其中向服务器发出的每个请求都包含一个唯一令牌,就像在 api 端点中一样。

所以,这就是我想知道的:

是否可以调整 passport.session() 以便如果没有找到会话 cookie,它会检查 req.token 并对此进行授权?

我注意到已经有一些基于令牌的 Passport 策略可用。 (例如https://www.npmjs.org/package/passport-http-bearer)然而,所有这些策略似乎都假设会话不会被使用,并且被关闭。我真正需要的是同时使用两者,因此如果一个身份验证失败(例如会话),它可以通过并检查另一个身份验证(令牌)。

有没有人实现过类似的东西?任何建议/指针将不胜感激。

【问题讨论】:

【参考方案1】:

这与导致我们编写 JSON Web Token 会话中间件模块的用例几乎完全相同。如果您使用的是 Redis,它应该很适合您的堆栈。

https://www.npmjs.org/package/jwt-redis-session

如果您将 requestKey 初始化参数更改为“jwtSession”而不是“session”,您可以将这个中间件与现有的基于 cookie 的会话中间件一起运行。然后在您的路线中,您可以检查 req.session.whatever 或 req.jwtSession.whatever 并处理独立于 cookie/JWT 传输机制的更高级别的功能。

您可能需要修改您的护照策略和/或序列化/反序列化功能,但将此中间件合并到现有的基于护照的应用程序中应该不会有太多工作。

不管你是否想使用那个模块,我认为你应该考虑使用基于 JSON Web Tokens 的东西。当用户进行身份验证时,您的服务器会将其令牌发送回 phonegap 应用程序,然后该应用程序将在每个后续请求中发送令牌。在这里,JWT 将简单地替换浏览器通过 cookie 支持的功能。通过 JWT 管理会话过期可能有点棘手,因为过期已包含在声明中,因此在不重新生成新令牌的情况下不可能“刷新”会话的 TTL。这就是导致我们回退到 redis 来管理过期的原因。

无论哪种方式,您都在寻找的不是随机生成的 UUID,而是一个加密的令牌,例如 JWT,它包含的会话标识数据刚好足以替换 cookie 的功能。

【讨论】:

以上是关于通过令牌进行身份验证,如果令牌失败,则通过会话进行身份验证,使用 Passport?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中从 Quickblox 进行身份验证和获取会话令牌

基于令牌的身份验证的安全性

Laravel - 使用会话令牌进行身份验证

如何跨不同 API 对 JSON Web 令牌 (JWT) 进行身份验证?

我是不是需要使用快速会话以及护照和 JSON Web 令牌进行身份验证?

如果身份验证令牌在帐户身份验证器中过期,则使用刷新令牌