15

我想为用户检查自动登录选项。基本上这意味着cookie将存储在客户端。

现在的问题是,我如何使它安全,这样 cookie 就不会被欺骗/修改。

我的一位朋友建议使用一个数据库表来存储 session_id、用户的 ip、浏览器信息等,然后在用户再次访问该网站时比较所有这些信息。

我觉得有一个单独的桌子有点太麻烦了。还有另一种方法吗?也许用令牌或类似的东西?

4

3 回答 3

26

你想要这个臭名昭著的 cookie 越安全,它给你带来的麻烦就越多。如果您的用户应该特别安全,您将不得不采用最麻烦的方法。

如果您想尽可能安全,您应该只接受带有 https 的 cookie。如果 cookie 通过 http 被接受,它可能会被嗅探和窃取。

我建议 cookie 根本没有用户数据(如您所建议的那样,一个令牌)。不幸的是,这将需要另一个表。当用户登录并选择“保持登录”时,在此表中创建一个条目。该条目可以是任何无意义的值(例如md5(uniqid('', true));。此标记在数据库中可以是唯一的并映射到用户的 ID。

当用户访问您的网站时,您可以检查该 cookie 的值并获取它所属的用户并登录。此时,您可以销毁旧令牌并创建一个新令牌。“毁灭”可能意味着很多东西。您可以将其从数据库中完全删除,也可以设置一个禁用令牌的标志。您可能希望允许多次使用相同的令牌,以防收到 cookie 但由于某种原因无法通过身份验证,但我认为这是不安全的。您可能还想存储令牌的时间戳,并且仅在某个有限的时间段内(例如 30 天)才接受它。

正如您的朋友指出的那样,您可以存储其他信息,例如用户代理、IP 地址等,但即使使用相同的浏览器(尤其是移动浏览器)并且如果用户的持久登录因此不被接受,这些信息也可能会发生变化, 这对他们来说可能很刺耳和不方便。

如果您真的不想创建另一个表,那么您将不得不存储一些方法来从 cookie 值中获取用户的 ID。这不太安全。

于 2011-09-29T02:42:23.940 回答
4

对于我知道的大多数自动登录,都有一个单独的表来存储登录会话。每个自动登录会话都分配了一个散列密钥作为标识符,该密钥相当长,几乎不可能被欺骗。如果您不希望用户使用有效代码跨 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 字符随机生成的字符串与之前生成的字符串相同的机会非常渺茫。

于 2011-09-29T02:43:45.083 回答
-4

我以前这样做的方式是存储密码的 MD5 哈希而不是实际密码。

在服务器端,您需要检查登录是否来自 cookie,然后在通过 MD5 散列后检查哈希是否与数据库中的密码相同

这样,如果有人入侵了用户的计算机,他们永远不会知道密码的值,但是仍然可以使用该 cookie 来仅对您的服务器进行身份验证。

您可以通过使 cookie 在 x 天后过期来提高安全性,因此如果 cookie 被盗,theif 只能在该期限内获得访问权限。

在一天结束时,最多也是唯一的?安全的方法是让用户每次登录

于 2011-09-29T02:26:55.077 回答