我有一个发送给用户的访问代码,以便他们可以一键访问该站点。从访问条款来看,它与密码重置 url 非常相似,所以我假设同样的假设适用。
例如,在这个问题中,人们建议散列这种类型的令牌,这听起来很合理,但问题是:如果我使用 bcrypt,我如何存储它以便我可以查询它或确保生成过程中的唯一性?除了检查数据库中的每个令牌之外,我看不到任何方法。
这是否意味着 bcrypt 不能用于该目的,或者我遗漏了什么?
我有一个发送给用户的访问代码,以便他们可以一键访问该站点。从访问条款来看,它与密码重置 url 非常相似,所以我假设同样的假设适用。
例如,在这个问题中,人们建议散列这种类型的令牌,这听起来很合理,但问题是:如果我使用 bcrypt,我如何存储它以便我可以查询它或确保生成过程中的唯一性?除了检查数据库中的每个令牌之外,我看不到任何方法。
这是否意味着 bcrypt 不能用于该目的,或者我遗漏了什么?
由于您知道您的纯文本令牌是唯一的(或者至少这是一个逻辑推理),因此您不需要盐。salt 的目的仅仅是在密码相同的情况下提供哈希唯一性,但是由于您的输入空间旨在保证唯一性,因此您没有这个问题。
此外,由于您可以控制明文的随机性和大小,因此您无需担心通过传统方式破解较弱的密码,因此实际上不需要 bcrypt 来减慢该过程。如果您的输入空间很大且是随机的,您可以使用无盐的强加密哈希(例如 SHA256)对其进行哈希处理。这使您可以H(token)在生成新令牌时简单地检查是否在数据库中(唯一性检查)。
H(token)验证重置请求的过程非常简单:获取用户 ID 和明文令牌(在重置链接中提供)并通过再次计算检查它们在数据库中是否匹配。
或者,如果您仍想使用 bcrypt,您可以通过在通过 bcrypt 之前将随机令牌与用户 ID 前置来确保唯一性。这不需要您验证唯一性(由于 ID 前缀,它始终是唯一的)并且仍然允许您很好地验证令牌。
您可以使用 bCrypt。简单的解决方案是向您的用户发送一个 Id 和令牌:
https://example.com/pwdReset?resetId=123&resetKey=[your long randomly generated key]
您可以使用 id 查找哈希(就像您使用用户名查找用户的密码哈希一样)。