Web services 处理到期/quot;“记住我”;JWT的功能

Web services 处理到期/quot;“记住我”;JWT的功能,web-services,rest,authentication,jwt,Web Services,Rest,Authentication,Jwt,从概念上讲,我非常喜欢JWT,因为它符合REST等的无状态性(没有保存状态的服务器端,所有相关数据都包含在令牌中) 我不确定的是:未连接时,您将如何处理令牌到期(即“记住我”功能) 网络上正在出现关于JWT的报道,但我还找不到任何人回答这个问题 澄清:我不是问如何处理即将过期的代币,而是问当代币已经过期时该怎么办(用户关闭网站/应用一段时间)。我想到的最简单的解决方案是缓存用户的凭据,这是相当不安全的。我不太确定是否遵循了,但我会写下我的想法 把代币想象成一张酒店卡,你可以提前5天付款(记住我设

从概念上讲,我非常喜欢JWT,因为它符合REST等的无状态性(没有保存状态的服务器端,所有相关数据都包含在令牌中)

我不确定的是:未连接时,您将如何处理令牌到期(即“记住我”功能)

网络上正在出现关于JWT的报道,但我还找不到任何人回答这个问题


澄清:我不是问如何处理即将过期的代币,而是问当代币已经过期时该怎么办(用户关闭网站/应用一段时间)。我想到的最简单的解决方案是缓存用户的凭据,这是相当不安全的。

我不太确定是否遵循了,但我会写下我的想法

把代币想象成一张酒店卡,你可以提前5天付款(记住我设定5天到期)。我可以在那5天内进入大楼、车库、房间等,在那5天之后,它将不再工作

当令牌已过期时该怎么办?什么都没有

想象一下,我付了那5天的钱,我有急事回家(口袋里有卡片)。酒店一点也不在乎,当这5天过去的时候,这张卡只是一块无用的塑料,如果你试图在酒店使用它,它将一事无成

那么回到web开发。如果您提供“记住我”服务,您可以将有效期设为7天。只要用户拥有令牌,他就可以毫无问题地访问服务。如果他丢失了令牌,他需要再次登录。如果他使用的令牌已经过期,他也需要再次登录

如果他登录,他将获得7天的代币,如果他不再使用代币,20天后他再次登录,他将需要再次登录,服务器将拒绝你的申请,直到你这样做

如果您在前端使用angular之类的工具,我会做的是在启动时检查令牌验证,这样您就可以拥有良好的用户体验


关于你的问题,我不明白的是去缓存的事情。

你需要在客户端上持久化JWT,以便它可以跨页面加载,最安全的策略是只使用HTTPS的cookie。这将在每次请求时将JWT发送到您的服务器,服务器可以检查令牌的有效性,并在令牌过期时拒绝它。如何处理过期取决于您拥有的web应用程序的类型

对于单页应用程序(例如Angular.js应用程序),您可能希望对应用程序进行结构化,以便它在引导应用程序的其余部分之前向服务器发出初始请求。如果服务器看到此请求中的JWT已过期,它将发出401响应。应用程序将通过呈现登录表单来响应此响应。否则,它将继续假设JWT是有效的,并且可以用于访问所需的资源。如果在任何时候,应用程序看到401,它应该将用户带回登录表单


对于在服务器上呈现页面的传统web应用程序:对于任何具有过期JWT(从cookie读取)的请求,服务器应向登录表单发出302重定向。

我想你要问的是如何使JWT服务器端的长过期令牌失效(例如“记住我”功能)

我自己最近也遇到了这个问题,最后使用了一个唯一的用户密码来使令牌无效,当用户尝试验证使用旧密码生成的令牌时,它将失败。用户名可以在解码的JWT预验证中找到


你甚至可以使用用户密码salt来实现这一点,这样当用户更改密码时,任何当前的JWT都会失效(假设你同时也更改了salt),这可能会有问题,尽管密码散列和JWT会紧密耦合

我可以想出一种方法,但这并不是真正的标准定义

在索赔中增加另一种不同寿命的到期日怎么样?对于两个声明,我们可以将其中较短的一个作为资源访问到期日,较长的一个作为刷新到期日,例如

{
    "iat": /* current time */,
    "bbf": /* current time + 1 hour -- expired means no resource access */
    "exp": /* current time + 1 week -- expired means cannot refresh */
}
(注意:我使用
bbf
表示更短的到期日期。没有具体原因,只是因为它有3个字符长。)

因此,选中“记住我”后,当用户重新连接时,他可以使用相同的令牌请求新的令牌,但不能访问资源。这样,所有相关数据都包含在令牌中——不需要额外的令牌

最后,当未选中“记住我”时,只需对
bbf
exp

使用相同的寿命。此外,您可以考虑实施刷新令牌系统:

在酒店示例中,您的酒店卡(访问令牌)在时间X之后将无效,但在接待处,您可以使用您的护照(刷新令牌)再次获取新的酒店卡

您可以将刷新令牌与用户正在使用的设备的其他数据一起存储在数据库中,以便用户在设备被盗时禁用该设备

例如:

  • 第一次正确的客户端登录:创建一个永远有效的刷新令牌(直到它被删除或失效)
  • 在数据库中存储刷新令牌
  • 将过期时间为的访问令牌(JWT)返回给客户端(此令牌未存储在数据库中)
  • 对于下一个请求,客户端发送访问令牌

  • 现在检查访问令牌是否过期:

    5.1访问令牌未过期,一切正常

    5.2访问令牌过期,检查数据库中是否有刷新令牌

    5.2.1刷新令牌在数据库中,返回新的访问令牌

    5.2.2数据库中没有刷新令牌,返回401/注销,用户必须重新登录


  • 希望这能有所帮助。

    对于如何解决这个问题,没有一个简单明了的答案