PHP: Best way to create and store token for confirmation email (3 options)
我想在PHP中创建一个令牌,它可以作为密码重置请求的一部分用于确认电子邮件。
在网上搜索时,我发现了一个帖子,上面写着:
有人能告诉我,与下面的相比,这里是否更适合这样做,并告诉我这里的区别是什么?
1
| $token = bin2hex(openssl_random_pseudo_bytes (16)); |
号
或
另外,您能告诉我应该使用哪种数据类型将这个数据存储在数据库中吗(使用MySQL)?
感谢您的到来,迈克
- @梅:非常感谢。您还可以让我知道应该使用哪种数据类型将这个存储在数据库中吗?如果你想把它作为答案寄出去,我会接受的。
- 顺便说一下,mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);提供16个字节(128位)。
不要将uniqid()用作任何安全关键代码中的随机值。这包括密码重置——攻击者可能能够预测uniqid()的值,允许他们猜测安全令牌并重置系统上任何用户的密码。
相反,使用bin2hex(openssl_random_pseudo_bytes(…))(在您的问题中看到)创建一个安全的随机令牌。php手册专门针对uniqid()上条目的脚注中的目的推荐此函数:
This function [that is, uniqid()] does not generate cryptographically secure tokens, in fact without being passed any additional parameters the return value is little different from microtime(). If you need to generate cryptographically secure tokens use openssl_random_pseudo_bytes().
号
由于bin2hex()是一个可打印的字符串,因此可以使用任何字符串类型将其存储在数据库中。在这里,VARCHAR应该是您的默认选择,这是完全合适的。
为了获得最大的安全性,您可能需要采取另外一个步骤。不要将令牌存储在数据库中,而是在数据库中存储令牌的哈希(例如,sha1($token)),然后将用户提供的值的哈希与存储的哈希进行比较。本质上,把它当作密码!这个额外的步骤将防止攻击者通过从数据库中读取用户的"忘记密码"令牌来获得对用户帐户的控制,因为攻击者能够读取您的数据库,但不能写入数据库。
- 非常感谢-这真的很有帮助!因此,对于令牌,我应该像在我的答案中那样使用$token=bin2hex(openssl_random_pseudo_bytes(16));还是必须添加或更改其中的任何内容?
- 另外,我喜欢存储令牌散列的想法。当按照您建议的方式存储数据时(在MySQL中),我必须使用什么数据类型?
- 是的,问题中给出的第二块示例代码是很好的。对于存储哈希,VARCHAR同样是非常好的。(通常,很少需要任何其他字符串类型。特别是,除了一些非常特殊的情况外,您可以完全忽略CHAR。
- 太棒了-谢谢!我应该用什么长度的varchar?
- 足够长以适合存储在列中的值。:)因此,如果直接存储bin2hex值,则至少32个字符,对于sha1哈希,至少40个字符。
- 再次感谢-你真的在这里帮助了我,它帮助我更好地了解了这个背景!:)