我想为用户检查自动登录选项。基本上这意味着cookie将存储在客户端。
现在的问题是,我如何使它安全,这样 cookie 就不会被欺骗/修改。
我的一位朋友建议使用一个数据库表来存储 session_id、用户的 ip、浏览器信息等,然后在用户再次访问该网站时比较所有这些信息。
我觉得有一个单独的桌子有点太麻烦了。还有另一种方法吗?也许用令牌或类似的东西?
我想为用户检查自动登录选项。基本上这意味着cookie将存储在客户端。
现在的问题是,我如何使它安全,这样 cookie 就不会被欺骗/修改。
我的一位朋友建议使用一个数据库表来存储 session_id、用户的 ip、浏览器信息等,然后在用户再次访问该网站时比较所有这些信息。
我觉得有一个单独的桌子有点太麻烦了。还有另一种方法吗?也许用令牌或类似的东西?
你想要这个臭名昭著的 cookie 越安全,它给你带来的麻烦就越多。如果您的用户应该特别安全,您将不得不采用最麻烦的方法。
如果您想尽可能安全,您应该只接受带有 https 的 cookie。如果 cookie 通过 http 被接受,它可能会被嗅探和窃取。
我建议 cookie 根本没有用户数据(如您所建议的那样,一个令牌)。不幸的是,这将需要另一个表。当用户登录并选择“保持登录”时,在此表中创建一个条目。该条目可以是任何无意义的值(例如md5(uniqid('', true));。此标记在数据库中可以是唯一的并映射到用户的 ID。
当用户访问您的网站时,您可以检查该 cookie 的值并获取它所属的用户并登录。此时,您可以销毁旧令牌并创建一个新令牌。“毁灭”可能意味着很多东西。您可以将其从数据库中完全删除,也可以设置一个禁用令牌的标志。您可能希望允许多次使用相同的令牌,以防收到 cookie 但由于某种原因无法通过身份验证,但我认为这是不安全的。您可能还想存储令牌的时间戳,并且仅在某个有限的时间段内(例如 30 天)才接受它。
正如您的朋友指出的那样,您可以存储其他信息,例如用户代理、IP 地址等,但即使使用相同的浏览器(尤其是移动浏览器)并且如果用户的持久登录因此不被接受,这些信息也可能会发生变化, 这对他们来说可能很刺耳和不方便。
如果您真的不想创建另一个表,那么您将不得不存储一些方法来从 cookie 值中获取用户的 ID。这不太安全。
对于我知道的大多数自动登录,都有一个单独的表来存储登录会话。每个自动登录会话都分配了一个散列密钥作为标识符,该密钥相当长,几乎不可能被欺骗。如果您不希望用户使用有效代码跨 IP 登录,请尝试此操作。
function gen_uniqueIdent($length=32){
$alphabet = str_split('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789');
$key = '';
for($loop=0;$loop<$length;$loop++){
$i = mt_rand(0,count($alphabet)-1);
$key.= $alphabet[$i];
}
return $key;
}
登录时将此值分配给用户 cookie。然后将其存储到数据库中:
function save_ident($identFromFunctionAbove,$authenticated_user_id){
//hash this with something unique to the user's machine
$hashed = md5($identFromFunctionAbove . $_SERVER['REMOTE_ADDR']);
/** Some actions to remember this hash **/
}
将其保存到与 user_id 等用户身份对应的数据库中。
现在在验证用户 cookie 后,您可以简单地:
function validateCookie(){
$ident = $_COOKIE['yourCookieName'];
$hashed = md5($ident . $_SERVER['REMOTE_ADDR']);
/** Check if this hashed value exists in db, if it does, authenticate user **/
}
您还需要在会话过期或用户明确注销后将其删除。
当然这很简单,不考虑 md5 或 ident 冲突。尽管如此,让两个 32 字符随机生成的字符串与之前生成的字符串相同的机会非常渺茫。
我以前这样做的方式是存储密码的 MD5 哈希而不是实际密码。
在服务器端,您需要检查登录是否来自 cookie,然后在通过 MD5 散列后检查哈希是否与数据库中的密码相同
这样,如果有人入侵了用户的计算机,他们永远不会知道密码的值,但是仍然可以使用该 cookie 来仅对您的服务器进行身份验证。
您可以通过使 cookie 在 x 天后过期来提高安全性,因此如果 cookie 被盗,theif 只能在该期限内获得访问权限。
在一天结束时,最多也是唯一的?安全的方法是让用户每次登录