如何在注销时销毁JWT令牌?

Gar*_*ima 42 node.js jwt hapijs

我在hapijs中使用jwt插件和策略.我能够在登录用户时创建jwt令牌,并通过'jwt'策略使用相同的令牌验证其他API.我在'request.state.USER_SESSION'中将令牌设置为一个cookie,其中USER_SESSION是令牌名称.另外,我没有将这些令牌保存在数据库中.但是如何在注销时销毁jwt令牌.请建议一个方法.

ped*_*ofb 53

JWT存储在浏览器中,因此删除在客户端删除cookie的令牌

如果您还需要在服务器端到期时间之前使令牌无效,例如帐户已删除/阻止/暂停,密码已更改,权限已更改,用户已由管理员注销,请查看为某些公共技术无效的JSON Web令牌创建黑名单或旋转令牌

  • 您在服务器端,您不能强制浏览器删除 cookie。但是您可以将该值设置为空并包含“expires”字段以使 cookie 值无效。请参阅 http://stackoverflow.com/questions/5285940/correct-way-to-delete-cookies-server-side。您还可以使用 javascript `var delete_cookie = function(name) { document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:01 GMT;'; 使客户端的 cookie 失效。};` (2认同)
  • @ChenNi,删除 HTTP-Only cookie 可以在服务器端完成(服务器发送带有新值的 set-cookie 标头)。令牌不会失效,但无法访问 (2认同)

Ama*_*pta 20

从客户端注销时,最简单的方法是从浏览器的存储中删除令牌。

但是,如果你想销毁节点服务器上的令牌怎么办 -

JWT 包的问题在于它不提供任何方法或方式来销毁令牌。

因此,为了销毁服务器端的令牌,您可以使用jwt-redis 包而不是 JWT

这个库 (jwt-redis) 完全重复了库 jsonwebtoken 的全部功能,并添加了一个重要的补充。Jwt-redis 允许您将令牌标签存储在 redis 中以验证有效性。redis 中缺少令牌标签使令牌无效。要销毁jwt-redis中的token,有一个destroy方法

它以这种方式工作:

1)从 npm 安装 jwt-redis

2)创建 -

var redis = require('redis');
var JWTR =  require('jwt-redis').default;
var redisClient = redis.createClient();
var jwtr = new JWTR(redisClient);

jwtr.sign(payload, secret)
    .then((token)=>{
            // your code
    })
    .catch((error)=>{
            // error handling
    });
Run Code Online (Sandbox Code Playgroud)

3)验证——

jwtr.verify(token, secret);
Run Code Online (Sandbox Code Playgroud)

4)摧毁-

jwtr.destroy(token)
Run Code Online (Sandbox Code Playgroud)

注意:您可以在登录令牌期间提供 expiresIn 与 JWT 中提供的相同。

  • jwt没有提供任何销毁方法,我在上面已经详细解释了这一点,因此我使用了jwt-redis包。所以,如果你看一下代码,我写了jwtr.destroy() (5认同)

Jam*_*yda 14

创建令牌后,您无法使其手动失效。因此,您实际上无法像会话那样使用服务器端的JWT注销。

JWT是无状态的,这意味着您应该将所需的所有内容存储在有效负载中,并跳过对每个请求的数据库查询。但是,如果您计划具有严格的注销功能,即使您已从客户端清除了令牌,也无法等待令牌自动过期,那么您可能需要忽略无状态逻辑并执行一些查询。那么有什么解决方案?

  • 为令牌设置合理的到期时间

  • 注销后从客户端删除存储的令牌

  • 在每个授权请求上针对“黑名单”查询提供的令牌

黑名单

所有不再有效且尚未过期的令牌的“黑名单”。您可以在文档上使用具有TTL选项的DB,该数据库将设置为令牌到期之前剩余的时间。

雷迪斯

Redis是blackblist的一个不错的选择,它可以在内存中快速访问列表。然后,在针对每个授权请求运行的某种中间件中,您应检查提供的令牌是否在The Blacklist中。如果是这样,则应抛出未授权的错误。如果不是,请放手,JWT验证将处理它并确定它是否已过期或仍处于活动状态。

  • 如果您告知此答案的来源,那就太好了:https://medium.com/devgorilla/how-to-log-out-when-using-jwt-a8c7823e8a6 (4认同)

Aks*_*Som 6

如果您只想删除令牌,那么只需从前端应用程序中删除它即可,在您的情况下清除存储令牌的cookie

另一方面,如果您打算使令牌无效,有几种方法可以做到这一点,以下是一些方法

(1)如果所有生成的令牌都存储在后端,则只需清除该存储即可简单,如果令牌已映射到用户,则只需清除特定用户的令牌即可。

(2)您可以添加一个日期字段,如“ invalidate_before ”以及用户,该字段应在更改密码、从所有设备注销等事件时更新。只需在此类事件上将invalidate_before更新为 currentTime() 即可。每次创建新令牌时,请在令牌有效负载中添加创建时间,以验证传入请求中的令牌,只需检查有效负载中的创建时间是否大于数据库中该用户的invalidate_before时间

(3)当您创建新用户时,仅为该用户创建一个密钥,然后您可以使用该特定密钥对每个用户令牌进行签名,就像(2)更改密码、从所有设备注销等事件一样,应该创建一个新的秘密。这样您也可以通过检查令牌签名来使之无效。

(2)(3)的开销是,验证将是一个两步过程,并且涉及数据库读取

编辑:对于(3) ,您可以使用盐(最终秘密将是公共秘密+特定用户的盐),这样您就可以通过更改盐来使单个用户的令牌无效,或者通过更改公共来使所有用户的令牌无效秘密