我正在滚动我自己的JWT令牌身份验证,但是,我真的希望它是一个时间令牌 - 所以一旦它被使用,服务器生成一个新令牌,客户端将不得不使用
。在下一次请求/呼叫期间该令牌。但是,据我所知,JWT应该是'无状态' - 但是通过一次性令牌的方法,我想我需要以某种方式存储有效的令牌,因为令牌将被刷新一次它被使用了。或者有没有办法避免在服务器上存储值,仍然能够创建一次性令牌?
我不想存储任何值的两个主要原因首先是可伸缩性(当然,我可以在中间使用缓存服务器来存储值,但如果不需要则会很好)其次,根据我的理解,JWT应该是无国籍的,如果我需要在服务器上存储一个值以便能够验证令牌,那么它就不会是无状态的。
有什么想法吗?
答案 0 :(得分:1)
当然存在解决方案。
与任何分布式系统(您提到的可扩展性)一样,您必须在可用性和一致性之间进行选择。
您选择可用性。在这种情况下,您可以维护一个已使用的令牌列表,您可以在所有端点之间以最终一致的方式复制这些令牌。例如,当使用令牌时,相应的端点将该令牌发送到背景中的其他端点。然而,有一个(短)时间框架,该代币可以被另一个端点第二次使用,直到更新该端点。
您选择一致性(您不会允许多次使用令牌)。在这种情况下,您使用具有已使用令牌的中央数据库,并在每次需要执行操作时检查该数据库。可扩展性?您可以在令牌上使用分片并拥有n
个数据库,每个数据库都负责一个令牌子集。
这取决于您的业务最适合的解决方案。
答案 1 :(得分:1)
使用用户当前密码的哈希值对JWT令牌进行签名,这样,成功更改密码之前生成的所有令牌将在下一次失效。我从这里https://www.jbspeakr.cc/howto-single-use-jwt/得到了这个主意。
答案 2 :(得分:0)
不是真的没有,如果JWT令牌没有过期并且签名是正确的,那么JWT令牌是有效的,通常人们会保留一份列入黑名单的令牌,通常是人们已经注销的等等。
我能想到的唯一明智的方法是给他们一个很短的到期时间并维护一份已经使用过的令牌列表,然后定期删除那些随后从DB过期的令牌。
实际上有一些数据库在记录上有一个TTL(dynamoDB,mongodb),因此您只需将令牌放入并为令牌过期时设置TTL。
答案 3 :(得分:0)
就像其他人提到的那样,这取决于您的业务案例。密码重置链接可以像在https://www.jbspeakr.cc/howto-single-use-jwt/上提到的那样。
如果您使用的是一次性使用和单一身份验证方案,那么您可能想使任何以前使用和未使用的令牌失效,则可以存储一个随机数,并在每个新令牌请求以及使用该令牌时对其进行更新。 / p>