我正在创造一个'记住我'的功能。我试图阅读许多不同的文档和手册,以确保它尽可能安全。
正如您所看到的,我正在创建一个$令牌,在验证cookie时,我们在MySQL数据库中查找并找到用户ID以将其登录。
我刚刚阅读了另一篇文章,其中建议我应该将一个RANDOM令牌以及一个SHA(384)的VERIFIER存储到cookie中,然后使用它们在MySQL数据库中查找它们。
我看不出它如何变得比下面的实现更安全,好像它们以某种方式拥有令牌,它们也会有验证者?
if ($remember == 1) {
$token = bin2hex(openssl_random_pseudo_bytes(16));
// insert token into the mysql database
$stmt = $pdo->prepare("INSERT INTO tokens (token, userid) VALUES(:token, :userid)");
$stmt->execute(array(
'token' => $token,
'userid' => $rRow->ID
));
setcookie ("MCTOKEN", $token, time() + 2419200,'/', SITE_DOMAIN);
}
答案 0 :(得分:0)
想象一下用户的cookie被嗅闻/被盗的情况:坏人只需在浏览器中创建具有嗅探值的mctoken即可立即访问用户的帐户。
你需要以某种方式来确保这种情况。这里有验证值。它将是一个包含数据的字符串,您可以在下次重现。最简单的例子是用户代理+盐。你可以想到别的什么。
在这种情况下,即使您同时拥有令牌+验证者,但验证值与当前环境不匹配,您也是安全的,用户也无法登录!
答案 1 :(得分:0)
您可以将两者存储在Cookie中,如果验证者在某种程度上是唯一的(可能验证用户代理或IP地址等),那么即使某人成功窃取了令牌,他的环境也可能与验证不匹配。但是,在服务器端也有一个验证器是个好主意,它可以验证与cookie中的验证器不同的东西。增加的安全性是这部分不会被盗。
答案 2 :(得分:0)
感谢您的回复,我想我现在明白了......我的更新代码如下...显然当我确认我需要使用相同的盐和'当前'用户代理来查看它们是否匹配。 ..
if ($remember == 1) {
$token = bin2hex(openssl_random_pseudo_bytes(18));
$salt = '#$RaNdSa48Lf:f';
$series = hash('sha256', $_SERVER['HTTP_USER_AGENT'] . $salt);
$expire = time() + 314496000;
// insert token and series into the database
$stmt = $pdo->prepare("INSERT INTO tokens (series, token, userid, expire) VALUES(:series, :token, :userid, :expire)");
$stmt->execute(array(
'series' => $series,
'token' => $token,
'userid' => $rRow->ID,
'expire' => $expire
));
setcookie ("MCTOKEN", $token .':'. $series, $expire, '/', SITE_DOMAIN);
}