我想知道最安全的cookie登录方式是什么? 如果只在cookie中存储加盐加密的密码和用户名,并根据用户表验证,潜在攻击者可以窃取cookie并登录。 人们通常不检查他们的'上次在线时间'。
那么是否有更好的“记住我cookie”方式? IP地址不是一个好的选择,是吗?(一些机器经常更改IP地址)。
我想知道最安全的cookie登录方式是什么? 如果只在cookie中存储加盐加密的密码和用户名,并根据用户表验证,潜在攻击者可以窃取cookie并登录。 人们通常不检查他们的'上次在线时间'。
那么是否有更好的“记住我cookie”方式? IP地址不是一个好的选择,是吗?(一些机器经常更改IP地址)。
我认为我找到了一个聪明的解决方案!
这个(复杂?)脚本的优点:
我在数据库中制作了以下信息的表:
session | token | username | expire
记住我的Cookie将被设置为:
$value = "$session|$token|$userhash"; //Total length = 106
Session
是一个由40个字符组成的字符串,采用sha1算法生成。Token
是一个由32个字符组成的字符串,采用md5算法生成。Userhash
是一个由32个字符组成的字符串,采用用户名的md5值生成。Username
是普通的用户名。Expire
表示60天后过期。脚本如下:
if(isset($_SESSION['check']) || $_SESSION['check']){
//User is logged in
}else if(isset($_COOKIE['remember']) && strlen($_COOKIE['remember'])==106){
//THERE is a cookie, which is the right length 40session+32token+32user+2'|'
//Now lets go check it...
conncectdb(); //Sets connection
//How do I protect this script form harmful user input?
$plode = explode('|',$_COOKIE['remember']);
$session = mysql_real_escape_string($plode[0]);
$token = mysql_real_escape_string($plode[1]);
$userhash = mysql_real_escape_string($plode[2]);
$result = mysql_query(" SELECT user
FROM tokens
WHERE session = '$session'
AND token = '$token'
AND md5(user) = '$userhash';")
if(mysql_num_rows($result)==1){
//COOKIE is completely valid!
//Make a new cookie with the same session and another token.
$newusername = mysql_result($result,0,0);
$newsession = $session;
$newtoken = md5(uniqid(rand(), true));
$newuserhash = md5($username);
$value = "$newsession|$newtoken|$newuserhash";
$expire = time()+4184000;
setcookie('remember', $value, $expire, '/', 'www.example.com', isset($_SERVER["HTTPS"]), true);
mysql_query(" UPDATE tokens
SET token='$newtoken', expire='$expire'
WHERE session = '$session'
AND token = '$token'
AND md5(user)='$userhash';");
//Set-up the whole session (with user details from database) etc...
} else if(mysql_num_rows(mysql_query("SELECT user FROM tokens WHERE session = '$session' AND md5(user) = '$userhash';"))==1)){
//TOKEN is different, session is valid
//This user is probably under attack
//Put up a warning, and let the user re-validate (login)
//Remove the whole session (also the other sessions from this user?)
} else {
//Cookie expired in database? Unlikely...
//Invalid in what way?
}
} else {
//No cookie, rest of the script
}
脚本的优点:
参考: http://jaspan.com/improved_persistent_login_cookie_best_practice
最流行的方式:
许多脚本使用某种会话跟踪。当用户首次访问网站时,它会为用户生成一个唯一的随机ID,并将会话信息存储在服务器和ID存储在cookie中。然后服务器使用唯一ID(称为会话ID)来识别用户。与会话ID关联的信息只能由服务器看到。PHP默认使用此功能。
有些将用户数据存储在cookie本身中,但使用密钥作为HMAC签名。如果签名不匹配,则脚本会丢弃cookie。这样,服务器就不必在服务器上保存会话数据。用户通过查看cookie来查看会话内容,因此您不应在其中存储敏感数据。仅用户ID(以及可能是登录时间和cookie过期时间)应该足够。虽然用户可以看到会话信息中的内容,但cookie中的签名确保用户不能自行修改会话数据。
这些方法提供了一定的安全性,使用户无法篡改会话数据,但并不能保护用户免受窃听者的攻击。他们始终可以使用数据包嗅探器从任何开放的WiFi网络中窃取会话。一些应用程序确实依赖于用户IP,但如果攻击者在同一网络中,则无关紧要。一些应用程序依赖于User-Agent,但当用户更新其浏览器或从另一个浏览器导入数据时,将会出现问题。
如果您真的关心安全问题,请使用HTTPS。
还要阅读这篇文章,特别是名为网站运营者如何解决问题?的部分。
身份验证请求
如果用户通过HTTPS进行身份验证并设置了“记住我”选项,则生成一个随机的记住我令牌,在服务器端的“记住我”数据库中存储它,并使用该值设置带有secure标志的记住我 cookie。然后开始一个新会话并设置记住我标志。
任何其他请求