当使用持久登录Cookie时,如何在DB中检查Cookie令牌与bcrypt-哈希令牌


How to check Cookie Token against bcrypt-hashed Token in DB when using Persistent Login Cookies?

这种流行的持久登录Cookie解决方案涉及生成一个随机的128位"令牌"以保存在用户的Cookie中,Jens Roland建议:

不要在你的数据库中存储持久的登录COOKIE(令牌)。只是一堆垃圾!登录令牌是密码等效的,所以如果是攻击者得到了你的数据库,他/她可以使用令牌登录任何账户,就像他们是明文一样登录密码组合。因此,使用强盐哈希(bcrypt/phpass)存储持久登录令牌

但是,当加密Cookie令牌总是产生不同的结果(因为加密总是使用随机盐)时,您如何根据数据库中的加密令牌检查Cookie令牌以确认Cookie登录是有效的?

换句话说,你不能只是加密Cookie令牌并在DB中寻找匹配,因为你永远不会找到一个,所以你如何根据推荐的解决方案("服务器保留一个数字->用户名关联表,查找以验证Cookie的有效性")在DB中实际匹配它?

编辑:

请记住,根据上面链接的推荐解决方案,单个用户可以为不同的设备拥有多个 cookie/令牌。我提到这一点是因为提交了一个答案(该答案已被删除),该答案假设每个用户只有一个Token。

正如前面的答案所提到的,bcrypt将随机盐作为哈希的一部分存储,因此数据库中的每个令牌条目将包括random_salthashed_token

当验证"记住我"登录cookie(应该由useridtoken组成)时,您将需要迭代该userid的每个令牌条目(通常只有一个条目,从不超过几个),并使用存储的随机盐分别检查每个条目:

foreach (entry in stored_tokens_for_user) {
    if (entry.hashed_token == bcrypt(cookie.token, entry.random_salt))
        return true;
}
return false;

(如果您的数据库内置支持bcrypt作为查询语法的一部分,您可以创建一个准备好的语句来为您完成此操作)