我正在使用在后端和基于JWT的身份验证中使用Go
的Web应用程序。当用户登录时,我向他们发送访问令牌(具有较短的到期时间)和刷新令牌(具有较长的到期时间)。这两个令牌都包含username
作为其有效负载。它们是用不同的秘密创建的。我的问题是关于注销。当用户发送注销请求时,我想使其刷新令牌无效,以便注销后需要他们再次登录。作为解决方案,我将刷新令牌存储在数据库的黑名单表中。我的问题是,在将刷新令牌存储在数据库中之前,是否应该对它进行哈希处理。谢谢。
标准JWT声明(RFC 7519 §4.1.7)之一是"jti"
,它是令牌的唯一标识符。如果您在刷新令牌中包含唯一标识符,则足以将"jti"
和"exp"
(到期)声明存储在数据库中。 (我默认使用("github.com/satori/go.uuid").NewV4
生成("github.com/satori/go.uuid").NewV4
作为随机UUID,并且在内部由"jti"
随机数生成器支持。)
现在,如果提供刷新令牌,则可以进行常规检查以确保其正确签名和未过期,然后在数据库中查找"crypto/rand"
。如果它不在黑名单中,那么它很适合重用。您只需要在数据库中保留"jti"
即可知道何时可以安全清除记录。由于"exp"
只是随机标识符,因此您无法从"jti"
返回任何可识别的信息,因此不需要特别对其进行哈希或加密。
如果您没有"jti"
并且不能添加一个,那么我可能会对该令牌进行哈希处理或仅保留声明的副本。部分原因是出于空间原因,部分原因是您不想存储实际上是有效凭证的内容。保留足够的信息,以便您可以唯一地标识令牌;可能"jti"
和"sub"
时间在一起就足够了(如果发给同一主题的两个令牌在同一秒到期,则无法区分)。