node.js - 在 NodeJS 中一次只允许从一台设备登录

标签 node.js json-web-token

我正在使用 JWT 进行身份验证。但是我不希望用户从多个设备登录。我如何确保这一点?

现在 - 我能想到的就是将 JWT 存储到数据库中,然后检查它是否存在。如果它存在,它是在什么时间生成的。如果时间太长 - 我们会重新生成 token 并传递回第二个设备。

最佳答案

这几乎是您唯一的选择,JWT 是故意无状态的。类似于如果没有类似的技术,您将无法真正进行服务器端注销

正如 jfriend 所指出的,单独存储 JWT 是不够的。您需要做的是确保下次用户请求登录时,他们还没有向他们发出未过期的 JWT。

遍历流程以确保完整性:

情况 1:用户未在任何地方登录。在这种情况下,JWT 被发布和存储。可能在用户记录中以便于检索。

情况 2:用户尝试在另一台设备上登录。无论您是让他们明确退出第一个设备还是为他们做这件事,您现在都必须将存储的 token 发送到已撤销的 token 列表中。在确定 token 是否有效时,您的 token 验证逻辑必须考虑该列表。

/* 进一步澄清 */

我觉得更多的细节可能对人们有用,所以我将深入实现。

** 未经身份验证的请求 **

这不应该改变,但值得一提的是,我假设您有需要身份验证的路由,并且对那些不包含事件和有效 JWT 的路由的请求会被 401 拒绝(并且可能提供了登录的 URL网址)。

登录

登录逻辑始终包括用户查找,因此如上所述,此应用程序中的流程应包括该查找,但在将用户登录到应用程序之前,您将检查是否已经为用户分配了未过期的 token 。

如果没有已分配给用户的 token ,则按照通常情况检查凭据,生成 JWT(带有 exp 标题以指示有效负载中的到期时间),将该 token 保存回用户文档/记录以备将来引用.

如果分配的 token 也未过期,则您必须将用户从其他设备注销(稍后将详细介绍),然后将其登录到当前设备,否则您必须拒绝登录尝试并让此人退出新设备。我认为前一种方法对用户更友好,但这取决于您的应用程序的需求。

登出

使用 JWT,保证用户无法使用已发布 token 的唯一方法是在有效负载中包含到期时间 (exp),并使用验证器进行检查,或者在服务器上了解哪些 token 不再是有效并检查它们。最强大的解决方案可以做到这两点。

因此,假设您已经在处理过期,显式注销功能将通过在某处创建一个已撤销的 token 列表来处理。例如,如果您使用 MongoDB,您将创​​建一个集合来存储这些。理想情况下,您还应该为每个设置为过期日期后某个时间点的 TTL 设置一个 TTL,以便 Mongo 将驱逐无论如何已过期的 token ,以节省您的时间和空间。

如果您对新的登录请求执行自动注销,当您将新 token 保存在用户文档中时,您将点击此逻辑将旧 token 放入已撤销的 token 列表中。

注销路由也应该可以由经过身份验证的用户访问,如果他们愿意,可以明确地注销,无论您是否执行自动注销。

经过身份验证的请求

至此,您应该可以合理地确定用户只能在一台设备上登录。但是,您还需要确保他们没有尝试使用已撤销的 token 发出请求。

然后,您的通用路由安全中间件还需要检查已撤销的 token 列表,以查看客户端提供的 token 是否在检查以确保未过期后是否在所述列表中(因为可以在验证时检查是否过期,从而节省了一轮-去数据库旅行。

关于node.js - 在 NodeJS 中一次只允许从一台设备登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42028920/

相关文章:

api - 使用 JWT 处理用户数据的最佳实践

javascript - 如何在 Javascript 中创建 JWT

python-3.x - 将 Json Web token 与 Flask-Oauthlib 结合使用

node.js - req.protocol 从不在 nginx 代理后面提供 https

node.js - 使用条件对内连接进行 Sequelize

javascript - 如何使用Puppeteer统计网页上特定文本的出现次数?

node.js - Webdriver-管理更新错误

angularjs - NodeJs中间件设置头

java - 在 java 中解析 A​​rmored ECC 公钥/私钥(从 gpg cli 生成)

node.js - grunt min 任务去哪儿了?