2011-09-29 81 views
15

我想为用户有一个自动登录选项检查。基本上这意味着cookie将被存储在客户端。在PHP中设计一个安全的自动登录cookie系统

现在的问题是,我该如何让它安全这样的cookie将不能被欺骗/修改。

我的一个朋友建议具有存储SESSION_ID,用户的IP,浏览器信息等,然后将所有这些信息,一旦用户进入该网站再次进行比较一个数据库表。

我觉得有一个单独的表,这是有点太麻烦。还有另一种方法可以做到吗?也许用令牌或类似的东西?

回答

26

的更安全,你想要这个臭名昭著的cookie,这将是你的更多的麻烦。如果你的用户应该特别安全,你将不得不采取最麻烦的方式。

如果您希望尽可能安全,则只应使用https接受此cookie。如果cookie通过http被接受,它可以被嗅探和窃取。

我会建议该Cookie具有完全没有用户数据(令牌,如你所说)。不幸的是,这将需要另一张桌子。当用户登录并选择“保持登录”时,请在此表中创建一个条目。该条目可以是任何无意义的值(例如md5(uniqid('', true));。该令牌在数据库中可以是唯一的,并映射到用户的ID。

当用户访问您的网站时,可以检查该cookie的值并获取用户它属于并登录它们,此时,你销毁旧的令牌并创建一个新的令牌,“销毁”可能意味着很多事情,你可以从数据库中完全删除它或者拥有一个禁用令牌的标志。希望允许多次使用相同的令牌以防万一接收到cookie但由于某种原因认证没有通过,但我认为这是不安全的。您可能还想要存储令牌的时间戳并且只接受它是否已经过了一段有限的时间(例如30天)。

A您的朋友指出,您可以存储其他信息,例如用户代理,IP地址等,但即使使用相同的浏览器(尤其是使用移动设备),这些信息也可能会更改,并且如果用户的持久登录未被接受,这可能会让他们感到不适和不方便。

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

+0

“当用户访问您的网站时,您可以检查该cookie的值并获取它所属的用户并将其登录”这样做的最佳方式是什么?只需将他们重定向到他们的用户/从数据库传递到安全页面? – CodeCrack

+0

@CodeCrack您可以完全控制用户是否已通过身份验证,因此确实没有最佳方式。只要在输入用户名/密码后做同样的事情。你可能已经(或者可以创建)一个函数或称为'complete_login()'的东西来为会话提供必要的数据。 –

+0

在登录时销毁旧令牌有什么好处?我认为那一刻也会有新的传递给客户,不是吗? – Uwe

-3

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

在您需要检查,如果登录是从一个cookie来了,然后检查哈希是相同的数据库中的密码,它是通过MD5

这样散列后,如果有人黑客服务器端用户计算机他们永远不知道密码的价值,但仍然可以使用该cookie来验证只有您的服务器。

您可以通过使x天后cookie的到期,所以如果cookie被盗小偷只能获得这一时期进入这个更安全。

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

+0

密码在存储之前应该已被散列。 –

+0

Tandu是正确的 –

+0

是的,加上他们可以使用彩虹表崩溃的密码。 – CodeCrack

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字符的随机生成的字符串与之前生成的字符串相同是相当渺茫的一个机会。

+0

一旦用户使用cookie登录,我是否必须手动设置SESSION变量,如果我正在使用它或更好,那么“会话”如何恢复? – CodeCrack

+0

@CodeCrack实际上,上面提到的方法是在php中创建自己的会话管理方法。所以基本上,是的,你必须手动设置SESSION变量来使用这个方法的PHP会话。 – Jabbany