仅允许在NodeJS中一次从一个设备登录

时间:2017-02-03 16:37:39

标签: node.js json-web-token

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

现在 - 我能想到的是将JWT存储到DB中,然后检查它是否存在。如果它存在,那么它产生的时间是什么时候。如果时间过长 - 我们会重新生成令牌并传回第二台设备。

2 个答案:

答案 0 :(得分:1)

这几乎是你唯一的选择,JWT在目的上是非常无状态的。类似于在没有类似技术的情况下如何无法真正执行服务器端注销

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

完成整个流程:

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

案例2:用户尝试登录其他设备。无论是使它们明确地从第一个设备注销还是为它们执行,您都必须将存储的令牌发送到已撤销的令牌列表中。在确定令牌是否有效时,您的令牌验证逻辑必须考虑该列表。

/ *进一步澄清* /

我觉得更多的细节可能对人们有用,所以我将稍微介绍一下。

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

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

<强>登录

登录逻辑总是包含用户查找,因此如上所述,此应用程序中的流程应包括该查找,但在将用户登录到应用程序之前,您将检查是否已经为用户指定了已分配的令牌没过期。

如果没有已分配给用户的令牌,则检查凭据,但通常会生成JWT(带有exp标题以指示有效负载中的到期时间),将该令牌保存回用户文档/记录中备查。

如果 分配的令牌也是未过期的,那么您必须将用户从其他设备中注销(更多内容会在一秒内),并将其登录到当前设备,否则您必须拒绝登录尝试并让该人员退出新设备。我认为前一种方法更加用户友好,但它取决于您的应用程序的需求。

<强>注销

使用JWT,保证用户无法使用已发布令牌的唯一方法是在有效负载中包含过期时间(exp),并使用检查该证书的验证者,或者在服务器上知道哪些令牌不再有效并检查他们。最强大的解决方案同时做到了。

因此,假设您已经处理过期,则可以通过在某处创建撤消的令牌列表来处理显式注销功能。例如,如果您正在使用MongoDB,则需要创建一个集合来存储它们。理想情况下,你也可以在到期日之后设置一个TTL设置到某个点,这样Mongo就可以驱逐那些过期的标记,以节省你自己的时间和空间。

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

注销路由也应该由经过身份验证的用户访问,以便在需要时显式注销,无论您是否执行自动注销。

经过身份验证的请求

到目前为止,您应该合理地确定用户只能在一台设备上登录。但是,您还需要确保他们没有尝试使用已撤销的令牌发出请求。

然后,您的通用路由安全中间件还需要检查撤销的令牌列表,以查看客户端提供的令牌是否在检查后确定它是否已过期(因为可以在验证时检查到期,保存往返DB的往返。

答案 1 :(得分:1)

我完全同意@Prateek Narendra。 用户登录后,将其令牌存储在数据库中(我将其存储在activeJWT字段中),然后在进一步登录时检查activeJWT是否为null。 如果是,则允许登录,否则不允许登录。 在注销时,您需要将activeJWT字段设置为空。 您可以为此解码当前令牌。