保护PHP记住我使用客户端cookie

时间:2012-09-09 08:05:19

标签: php mysql cookies

我知道这个问题可能会被多次询问,但大多数建议你存储ip +用户名+密码并将这一切都哈希并进行比较,相反,我为我的网站想出了一个不同的解决方案,我想做点什么像这样:

使用会话存储用户名,用户ID,时区偏移等,现在假设我们说用户登录并且他检查了记住我,我将设置会话然后我将生成一个变量uniqueid持有随机的12-13位数字ID,设置完成后我会在他的浏览器上使用这个唯一的ID和用户名创建一个cookie,并将其存储在我的数据库中,当他回来时我将检查该id和用户名cookie是否为设置如果是,而不是选择用户名,请记住来自数据库的用户名= cookie用户名,然后再次设置会话并将其扔到主页上,否则重定向到登录页面。

如果他退出我将删除所有cookie并在他选择记住并登录后更新唯一值...

这样做有什么问题吗?还是更好的方法呢?我不希望密码保存在cookie中,即使是在散列状态下......或者我在做什么是完美的?

2 个答案:

答案 0 :(得分:3)

因此,据我了解您的描述,当用户登录(并希望保持永久登录状态)时,您可以执行以下操作:

  • 创建随机令牌。
  • 将随机令牌保存在该用户的用户数据库记录中(或在包含用户名和令牌的单独表中)。
  • 在用户浏览器中设置包含用户名和令牌的Cookie。

当用户返回并且没有活动会话,但确实有上面设置的cookie时,您在数据库中查找他们的用户名。如果数据库包含该用户的“记住我”令牌,并且该令牌与cookie中的令牌匹配,则为该用户创建一个新会话。

当用户注销时,您从浏览器中删除cookie,并从数据库中删除令牌。


如果是这样,这是一个非常安全的设计,只要令牌足够长并且由安全的随机数生成器(如Unix上的/dev/urandom)生成。你说你的标记是“12-13位长”,这意味着你的标记超过40位;这有点偏低,我建议至少两倍。另外,你没有说如何你正在生成令牌;只使用PHP的randmt_rand是不安全的,因为它们的输出可能是可预测的。

我还建议两个改进:首先,在将令牌存储到数据库之前对令牌进行散列(任何加密散列函数都会执行,例如SHA-1 - 使用长随机令牌,您不需要任何特殊的密码散列函数,如PBKDF2)以便设法复制数据库的攻击者无法获得所有令牌。其次,在数据库中包含令牌的到期日期,以便单个受损令牌永远不会保持有效。

答案 1 :(得分:1)

您永远不必在cookie中存储用户名和/或密码。您需要存储的是一个唯一的标识符(随机生成),可以与数据库中的散列会话标识符进行比较。