构建包含激活或密码重置令牌的链接的最佳方法是什么?该URL将通过电子邮件发送,用户可以点击它来激活他们的帐户或重置他们的密码。这有很多线程,但似乎没有一致的方法,从安全和开发的角度来看,每种方法似乎都有优点和缺点:
链接包含令牌作为查询字符串中的参数和电子邮件地址
http://www.example.com/activations/:token?email=joe@gmail.com
使用此方法,令牌在数据库中进行哈希处理,电子邮件用于查找用户。然后使用像brycpt这样的库将令牌与数据库中的散列版本进行比较。似乎包括敏感数据,例如查询字符串中的电子邮件地址,exposes some security risks。
链接仅包含令牌作为参数或查询字符串。
http://www.example.com/activations/:token
这似乎是理想的解决方案,但我不知道如何比较令牌,除非存储在数据库中的令牌未散列。从安全的角度来看,有些人认为token in the database doesn't need to be hashed,而其他人认为token should be hashed。假设我们在数据库中保留一个哈希标记,迭代数据库中的每个标记并与链接中的标记进行比较似乎非常耗时,特别是在拥有大量用户的应用程序中。所以也许我对此错了,但似乎使用这种方法需要我将数据库存储在数据库中,并且没有发挥作用。
有人对最佳方法有任何想法吗?
答案 0 :(得分:0)
没有反对使用仅包含令牌的方法2的论据。
正确的是,只应将令牌的哈希值存储在数据库中(SQL注入)。您看到的问题来自于使用BCrypt:
这两种技术,即腌制和键拉伸,对于存储弱密码是强制性的,它们使得暴力破坏变得不可行。因为我们的令牌是一个非常强大的密码" (最少20个字符0-9 a-z A-Z)不需要这些技术,您可以在数据库中存储令牌的未加盐的SHA-256。可以使用SQL直接搜索这样的哈希。
为了表明它真的很安全,让我们做一个简单的计算。一个20个字符的标记将允许7E35组合。如果我们可以计算出3 Giga SHA-256 per second,那么我们仍然可以期待大约3到700&000; 000' 000' 000' 000年来找到匹配。
只需确保令牌是从加密随机源创建的。