我需要散列存储在数据库中的刷新令牌吗?

Do I need to hash refresh token stored in database?

我正在开发一个在后端使用 Go 和基于 JWT 的身份验证的 Web 应用程序。当用户登录时,我向他们发送过期时间较短的访问令牌和过期时间较长的刷新令牌。这两个令牌都包含 username 作为它们的有效负载。它们是用不同的秘密创建的。我的问题是关于注销。当用户发送注销请求时,我想让它的刷新令牌无效,以便他们在注销后需要再次登录。作为解决方案,我打算将该刷新令牌存储在我的数据库中的黑名单 table 中。我的问题是,在将刷新令牌存储到数据库之前,我是否需要对其进行哈希处理。谢谢

标准 JWT 声明之一(RFC 7519 §4.1.7) is "jti", which is a unique identifier for the token. If you include a unique identifier in your refresh token, then it's enough to store the "jti" and "exp" (expiration) claims in the database. (I'd default to using ("github.com/satori/go.uuid").NewV4 生成 "jti" 作为随机 UUID,并且由 "crypto/rand" 随机数生成器内部支持。)

现在,如果您看到一个刷新令牌,您可以进行常规检查以确保它已正确签名且未过期,然后在数据库中查找 "jti"。如果它不在黑名单中,那么它可以重复使用。您只需要在数据库中保留 "exp" 即可知道何时可以安全地清除记录。由于 "jti" 只是一个随机标识符,您无法从 "jti" 返回任何可识别信息,因此没有特别需要对其进行哈希处理或加密。

如果您没有 "jti" 并且无法添加,我可能会散列令牌或只保留声明的副本。部分原因是 space,部分原因是您不想存储实际上是有效凭证的内容。保留足够的信息,你可以唯一地识别一个代币; "sub""exp" 时间在一起可能是足够的信息(如果发给同一主题的两个令牌在同一秒到期是无法区分的)。