php – 使用会话和Cookie安全登录
我目前使用会话将用户登录到我的网站.现在,我想在混合中添加cookie,以便人们可以在几天后访问该网站,而无需再次登录.
我不想将密码存储在cookie中或加密任何东西 – 所以我的解决方案是将用户名存储在cookie中,并使用一种登录哈希(特定于每个用户的每次登录)创建另一个cookie.然后,在每个页面的顶部,检查cookie和登录会话.如果cookie存在但会话不存在,请找到用户名并将用户登录. 因此,这会在他们成功登录后发生($row [‘username’]是他们输入的用户名): $_SESSION['username']=$row[username]; $_SESSION['user_id']=$row['id']; $loginhash = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),32); $number_of_days = 14; $date_of_expiry = time() + 60 * 60 * 24 * $number_of_days ; setcookie( "userlogin",$row['username'],$date_of_expiry,"/" ) ; setcookie( "loginhash",$loginhash,"/" ) ; $today=date("Y-m-d"); mysql_query("update members set last_login='$today',loginhash='$loginhash' where id='$row[id]' ") or die(mysql_error()); 然后在每个页面的顶部,执行以下操作: if($_COOKIE['userlogin'] && !isset($_SESSION[user_id])){ $username=mysql_real_escape_string($_COOKIE['userlogin']); $loginhash=mysql_real_escape_string($_COOKIE['loginhash']); $result=mysql_query("select * from members where (username='$username' || email='$username') && loginhash='$loginhash' ") or die (mysql_error()); $row=mysql_fetch_array($result); $_SESSION['username']=$row[username]; $_SESSION['user_id']=$row['id']; } 然后,当然,当用户手动注销时取消设置cookie. 我的问题是,这是否安全(除了其他人使用用户计算机的危险)?为每次登录生成随机哈希,因此有人不能仅使用某人的用户名创建cookie并以该人身份登录. 登录脚本使用HTTPS,因此该方面没有危险. 解决方法
不,这不安全!
我可以看到你这样做的两个主要问题: >我们不在数据库中存储密码的原因是,如果数据库受到攻击,攻击者无法访问我们服务器上的帐户……但这正是您正在使用的loginhash.如果我危害您的数据库,我可以通过使用用户名和数据库中的loginhash创建一个cookie,以便在接下来的14天内以任何具有活动cookie的用户身份登录. 您可以通过生成随机密钥,将其存储在cookie中,然后通过像bcrypt这样的散列函数运行它并将摘要存储在数据库中来纠正此问题.这样,即使完全转储数据库,用户也不能像其他任何用户一样简单地登录您的站点.当然,您必须更改比较运算符,以便比较摘要而不是原始数据. 改编自this password reset class: function generateRandomBase64String($length = 32) { if (!defined('MCRYPT_DEV_URANDOM')) die('The MCRYPT_DEV_URANDOM source is required (PHP 5.3).'); $binaryLength = (int)($length * 3 / 4 + 1); $randomBinaryString = mcrypt_create_iv($binaryLength,MCRYPT_DEV_URANDOM); $randomBase64String = base64_encode($randomBinaryString); return substr($randomBase64String,$length); } 现在,我们需要让饼干顶升更加困难 This article解释了Drupal如何处理登录令牌,每次用户使用凭据登录而不是使用cookie时,将用户名,loginhash和series_id存储在一起.可以使用上述随机函数生成loginhash和series_id. 用户登录时,将检查数据库.如果用户名,loginhash和series_id都存在,则用户登录并生成具有相同用户名和series_id但新loginhash的新cookie.这意味着每个cookie只能使用一次. 此外,以这种方式登录的用户无法执行任何妥协功能,例如请求密码重置,取款和查看敏感信息而无需“正确”密码登录.这是为了保护已经拥有cookie的用户. 如果检测到登录系统存在series_id但loginhash不匹配,我们会擦除该用户的所有有效cookie,并留下一条措辞强烈的消息,表明使用了无效的cookie来访问其帐户. 在旁边注意重新mysql_ *函数 这似乎是新代码,尚未部署.如果还不太晚,请考虑将数据库驱动程序切换到mysqli(documentation),它保持与mysql非常相似的过程样式,但允许您使用绑定参数和其他现代函数来提高数据安全性. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |