JWT 方法中的自定义刷新令牌方法

Posted

技术标签:

【中文标题】JWT 方法中的自定义刷新令牌方法【英文标题】:custom refresh token method in JWT method 【发布时间】:2018-02-14 14:51:08 【问题描述】:

根据这篇文章http://www.jianshu.com/p/b11accc40ba7 保护 JWT 的一种方法是 refreshToken:

在中心认证服务器中,我们维护一个这样的表:

table auth_tokens(
    user_id,
    jwt_hash,
    expire
)

以下是工作流程:

用户用手机请求登录API,我们验证后,认证服务器发送一个令牌,并注册令牌(在表格中添加一行。)

当令牌过期时,用户使用旧令牌请求交换 API。首先身份验证服务器正常验证旧令牌,除了过期检查,然后创建令牌哈希值,然后通过用户 id 查找上表:

一个。如果找到的记录与 user_id 和 jwt_hash 匹配,则发出 new 令牌并更新表。

b.如果找到记录,但 user_id 和 jwt_hash 不匹配,则表示 有人曾经使用过该令牌交换了新令牌。令牌是 被黑,按 user_id 删除记录并用警报响应 信息。

c。如果没有找到记录,用户需要重新登录或只输入密码。 使用更改密码或登出时,按用户ID删除记录。

要持续使用token,合法用户和黑客都需要不断交换新的token,但只有一个可以成功,一个失败,下次交换时都需要重新登录。

所以如果黑客拿到了token,可以短时间使用,但是如果合法用户下次换新,就不能换新了,因为token有效期短,安全性更高。

如果没有黑客,普通用户也需要定期交换新令牌,比如每30分钟一次,这就像自动登录一样。额外的负载并不高,我们可以为我们的应用调整过期时间。

但想象一下这个情景:

例如,黑客获得了 Bob 的令牌,他知道 Bob 在凌晨 1:00 到 6:00 睡觉, 因此,黑客可以在晚上连续使用令牌,直到 Bob 第二天起床并使用该应用程序。

一个解决方案是在晚上,用户应该输入用户并通过而不是令牌,但这在我的想法中不是一个好的解决方案! 你知道更好的解决方案吗?

提前致谢

【问题讨论】:

【参考方案1】:

这个解决方案缺点很多,优点很少:

需要服务器存储。你失去了 JWT 的无国籍状态。即使是永远不会被撤销的令牌

tokens,其实可以永远使用只是用旧的刷新一下

每个用户一个令牌意味着只有一个设备使用 API。例如,在移动设备上登录会使桌面浏览器中的会话无效

攻击者可以在用户睡觉时使用令牌(如您所指)

然后,优点:您可以撤销令牌。如果您真的需要它(建议 JWT 让令牌过期),我相信有一些简单的方法可以实现它。见Invalidating client side JWT session


请注意,您的问题开始谈论“刷新”令牌,但后来​​您描述了一种自定义机制来刷新和撤销,这无关紧要。刷新令牌是长期存在的,持久的,仅用于获取短期访问令牌

【讨论】:

感谢您的回复。那么刷新令牌如何工作?实现刷新令牌的最佳做法是什么? 你可以阅读这篇文章auth0.com/blog/…和这篇关于在oauth2协议***.com/questions/3487991/…中定义的刷新和访问令牌的线程 @pedrodb 谢谢我阅读了这两个链接并更改了我的问题的标题。我知道我们需要服务器存储来拥有黑名单用户。你能读懂这个问题吗? ***.com/questions/46093214/… 是的。为了维护一个黑名单,需要在服务器端存储被撤销的令牌(或者只是唯一标识符jti 或最后发布日期)直到到期时间。我会看看你的新问题。您需要对这个问题做一些额外的说明吗?

以上是关于JWT 方法中的自定义刷新令牌方法的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 自定义 JWT 过滤器不允许任何没有令牌的请求

如何使用访问和刷新令牌返回自定义数据以识别 Django Rest Framework 简单 JWT 中的用户?

PHP 中的自定义 JWT 一直说签名无效

JWT 身份验证不适用于 Django 中的自定义控制器

向 ASP.NET Core 的 JWT 令牌添加自定义验证?

使用 IdentityServer 与创建基于 JWT 的自定义身份验证