JWT 有效负载中的令牌

Posted

技术标签:

【中文标题】JWT 有效负载中的令牌【英文标题】:Token inside JWT payload 【发布时间】:2019-10-29 06:39:25 【问题描述】:

在 JWT 有效负载中包含一个随机生成的令牌并在每个请求上检查数据库是否是个好主意?

我已经对 JWT 及其实际工作原理进行了研究,我知道它的主要目的是避免在每次请求时查询数据库以授权用户,但我仍然必须这样做,因为我需要一些关于发出请求的用户。

如果需要,我还需要一个好的解决方案来立即撤销令牌。 最初将令牌列入黑名单似乎是一个很好的解决方案,但这需要额外的请求,我认为这不值得。

所以我想出的解决方案是生成一个随机令牌并将该令牌保存在我的数据库中,并将其放入 JWT 有效负载中。 这样,当用户发出新请求时,它首先检查 JWT 令牌是否有效,如果有效,则检查负载中关联的令牌是否有效。

因此,例如,如果用户需要更改他的密码,他的令牌将会更改,并且其有效负载中包含先前令牌的所有 JWT 令牌都将无法验证。

所以解决方案是这样的:

当用户注册时,它会被分配一个随机令牌,并存储在有效负载中。如果注册成功,服务器返回生成的jwtToken。

var jwtToken = jwt.sign(token: randomToken, PRIVATE_KEY, SIGN_OPTIONS);

所以当用户发出新请求时,它首先会检查 JWT 令牌是否有效。

var legit = jwt.verify(token, JWT_PUBLIC_KEY, SIGN_OPTIONS);

如果是,则继续使用数据库中的用户令牌检查有效负载内的令牌。

SELECT * FROM users WHERE token = legit.token

如果一切正确,则继续正常请求。

【问题讨论】:

这违背了使用 JWT 的全部意义。您说您理解这一点,但如果您必须进行数据库查找,实际上您不应该使用 JWT。 dzone.com/articles/stop-using-jwts-as-session-tokens @TheGreatContini 感谢您的链接。他说的完全有道理,但我忘了提到我的意图是在我的移动应用程序中使用它,正如文章所说,“如果你正在构建需要支持服务器到服务器或客户端到服务器的 API 服务-服务器(如移动应用或单页应用 (SPA))通信,使用 JWT 作为 API 令牌是一个非常聪明的想法。” 【参考方案1】:

“这是个好主意吗...”不是一个很好的提问方式,但我会尽力回答...

1。 JWT 是安全的

私钥背后的原因是为了确保用户不会更改令牌。因此,将经常使用的对象存储在令牌中是完全安全的,无需将令牌存储在任何地方。签名的对象如下所示:


  expirationDate: 1560530063664,
  ...user data

2。黑名单和撤销令牌

要将某个令牌列入黑名单,我认为最好的方法是您想出的方法。根据您同时访问该网站的用户数量,使用阵列大腿可能/一个好主意。

虽然拥有将令牌列入黑名单的能力可能很好,但真的有必要吗?如果用户更新了他们的密码,他们真的需要注销吗?如果你仍然认为你需要一个令牌存储,我相信有多个 npm 包可以这样做......

【讨论】:

您好,感谢您的回复。我知道 JWT 非常安全。但是,如果令牌被盗,它将在到期之前一直有效。因此,如果我不对每个请求都使用数据库进行检查,即使已向用户颁发了新的 JWT 令牌,它仍然有效。 好吧,虽然它可能会发生,但很可能不会发生,除非您将到期日期设置为 > 一周,否则用户很可能在到期之前不会注意到这一点。 虽然,您可以有一个带有令牌的黑名单,当它们过期时,您可以将它们从黑名单中删除。但这意味着您要么使用数据库,要么单步执行数组,并且根据有多少用户报告他们的帐户被盗,这可能需要一些时间......

以上是关于JWT 有效负载中的令牌的主要内容,如果未能解决你的问题,请参考以下文章

解析 JWT 令牌有效负载数据以在 android/java [关闭]

firebase如何发送一个有效负载包含下划线字符的JWT令牌?

JSON Web 令牌 - 有效负载中的密码?

提取过期 jwt 令牌的有效负载

在MEAN堆栈应用程序中自定义JWT令牌的有效负载

没有任何 JS 访问令牌的 JWT 有效负载加密