我目前正在这样做:
function setlogincookie($user_id) {
$user_id = $user_id;
$day = new DateTime('+1 day');
setcookie('session','1',$day->getTimestamp(), $user_id, null, null, true);
}
但它将用户的ID存储为纯文本。如何让它显示一个随机整数,但仍然可以像用户1一样登录?我可以使用password_hash然后在代码中验证它吗?或者有更好的方法。
答案 0 :(得分:1)
你的意思是long-term "remember me" authentication cookie?随机令牌和查找表通常是接近它的最佳方式。 (链接的文章也深入探讨了一些“主动安全”的策略。)在讨论URL parameter encryption时,我提出了类似的论据,支持随机令牌而不是加密功能,并在讨论PHP session security时触及它。 / p>
让我们更广泛地看一下:您希望将信息存储在cookie中(用户可以随意欺骗/篡改)。您不希望用户在更改cookie时获得任何有意义/有用的结果。 (理想情况下,你的代码会去,“这是不对的”,并将它们视为未经过身份验证。)
答案是use authenticated encryption。有两个库提供了一种简单易用的方法来满足这一要求(免责声明:我对两者都做出了贡献,所以在考虑使用之前你应该问一个cryptography expert。
Halite(即将推出的第一个稳定版本)是一个包装the PHP bindings for libsodium的PHP库,使其更易于使用。开箱即用的其中一个类是\ParagonIE\Halite\Cookie
。
请注意,Halite需要libsodium的PHP扩展(在PECL中可用)。如果那是不行的,那么你可能想要......
其名称最常见于Packagist,defuse/php-encryption,这与PHP 5.4 +开箱即用。
版本2即将推出,但如果您今天需要解决方案,请抓住1.2.1版本并执行此操作:
$enc_key = Crypto::CreateNewRandomKey(); // Store me!
// Storing a cookie:
setcookie(
'name',
Crypto::binToHex(Crypto::encrypt($value, $enc_key))
// other parameters
);
// Reading a cookie
try {
$cdata = Crypto::decrypt(
Crypto::hexToBin($_COOKIE['name']),
$enc_key
);
} catch (Exception $e) {
$cdata = null;
}
答案 1 :(得分:0)
这将使得令牌中的任何内容都可以通过仅具有私钥的存储服务器端的MAC进行身份验证。加密不是必需的,因为MAC将阻止用户ID被更改,因为攻击者将没有私钥来验证他们自己的更改。
确保"有效载荷数据"包含足够的用户会话及其使用意图,使其有意义。也就是说,不要单独存储用户ID,因为攻击者可能能够使用应用程序中其他位置的JWT模拟用户ID,如果您存储的只是一个数字。始终包含一个到期日期,以防止无限期保存JWT。