使用Cookies和盐哈希的PHP登录系统

18

我正在开发基于PHP的登录系统。 每个用户都有一个ID(数字)和一个密码,存储为盐值哈希。

我能够判断登录是否成功,但现在需要将该信息存储在某个地方(以便用户不会永久注销)。

过去,我曾尝试使用$_SESSION变量。但是,当用户离开浏览器时,这些变量似乎会被删除,这是不希望的。 此外,我不能“假设”用户不会尝试欺骗系统,因此必须安全。

所以,这里是我的问题:

  1. 我应该使用$_SESSION还是$_COOKIE?每种方法的主要优点是什么?
  2. 如何实现“记住我”的复选框?
  3. 应将哪些信息存储在会话/cookie变量中?

请注意,此特定问题未考虑任何数据库安全问题。

关于第3个问题,我的意思是:

  • 我应该在cookie / session中存储用户的ID和哈希密码,还是
  • 我应该在cookie / session中存储用户的ID和非哈希密码,还是
  • 我应该存储一个“SessionID”和密码(哈希或非哈希?)或
  • 我应该存储“SessionID”,“ID”和密码(再次,哈希或非哈希)?

我想尽可能保持我的网站安全,高效且用户友好。 如果采用基于SessionID的方法,我也希望获得有关如何将其存储在数据库中的说明。

谢谢您提前

注:此答案只是翻译,不代表具体技术建议。


尽可能重用现有的身份验证框架,因为它们是复杂的。例如,请查看https://github.com/delight-im/PHP-Auth。 - caw
3个回答

9

我想重申Eran的观点,绝不能在会话或cookie数据中存储用户密码或密码哈希值。

通常情况下,我使用Cookie来实现Web应用程序中的“记住我”功能。建立“安全”的持久登录系统的信息,可以从这篇Fishbowl博客文章开始了解。更深入的回答已经在另一个Stack Overflow答案中介绍了。

如果您需要确保登录安全,必须使用https。这是因为未加密的Cookie或会话可能会被盗取。

另一个好的实践是使用2级登录系统。您可以在亚马逊等网站看到这一点,在不登录的情况下将商品添加到购物车中,但如果要结账或以某种方式编辑帐户,则必须再次输入密码。


1
这篇后续文章将把它提升到下一个级别:http://jaspan.com/improved_persistent_login_cookie_best_practice - jmucchiello
@jmucchiello很不幸,“改进”的方案并没有意义。还请阅读:https://dev59.com/vnVD5IYBdhLWcg3wXaid#477579 - Jacco

8

对于敏感信息(如身份验证结果),请仅使用会话。会话存储在服务器端,不太可能被攻击。

关于会话的生命周期,默认值是浏览器会话的生命周期 - 但您可以控制它。有几个设置会影响它:

session.gc_maxlifetime - 实际上控制会话的生命周期。

session.gc_probability 和 session.gc_divisor 共同确定会话垃圾回收将发生的频率。

最后 - session.cookie_lifetime 控制会话 cookie 的生命周期(保存会话 ID 的 cookie,以便无需通过 URL 传输)。它应该与 session.gc_maxlifetime 的值相匹配。

此外,永远不要在会话或 cookie 中存储密码(即使是哈希格式)。只存储身份验证的结果。


0

将ID存储在$_SESSION中,但不要存储散列或非散列密码。一旦用户登录并且ID保存在$_SESSION中,您就不再需要密码了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接