我正在使用一种非常标准的 cookie 登录方式 - 我给用户两个 cookie,一个带有他的用户名,另一个带有随机生成的字符串和用户特定的盐。
这是登录时发生的情况:
$_SESSION['username']=$row[username];
$_SESSION['user_id']=$row['id'];
$loginhash=generateRandomBase64String()."_".$row['salt'];
$number_of_days = 14;
$date_of_expiry = time() + 60 * 60 * 24 * $number_of_days ;
setcookie( "userlogin", $row['username'], $date_of_expiry, "/" ) ;
setcookie( "loginhash", $loginhash, $date_of_expiry, "/" ) ;
$cryptedhash=crypt($loginhash);
$today=date("Y-m-d");
mysql_query("update members set last_login='$today',loginhash='$cryptedhash' where id='$row[id]' ") or die(mysql_error());
所以这个$loginhash
值类似于Pe0vFou8qe++CqhcJgFtRmoAldpuIs+d_g5oijF76
它的加密版本存储在数据库中。salt 已经在数据库中,因为它是在每个用户注册时为他们生成的。
我$_SESSION[username]
使用会话变量(问题是,哈希永远不正确。$_SESSION[username]
$_COOKIE[userlogin]
if($_COOKIE['userlogin'] && !isset($_SESSION[user_id])){
$username=mysql_real_escape_string($_COOKIE['userlogin']);
$loginhash=mysql_real_escape_string($_COOKIE['loginhash']);
$salt=substr($loginhash,-8);
$result=mysql_query("select * from members where (username='$username' || email='$username') && salt='$salt' limit 1 ") or die (mysql_error());
$row=mysql_fetch_assoc($result);
$cryptedhash=$row['loginhash'];
if (crypt($loginhash, $cryptedhash) == $cryptedhash){
$_SESSION['username']=$row[username];
$_SESSION['user_id']=$row['id'];
}
}
$_COOKIE[userlogin]
是正确的值。当我检查数据库中的用户名/盐组合时,找到了正确的结果(echo $row[username]
给出正确的值)。但是,if
从未满足以下条件。我认为我的 PHP 配置有些奇怪,但我使用相同的加密机制来存储密码并且它可以正常工作。
那么任何人都可以看到这里出了什么问题吗?
PS 我不想在这里开始讨论 cookie 安全或各种可用的哈希函数。