【问题标题】:Correct way to manage sessions in PHP?在 PHP 中管理会话的正确方法?
【发布时间】:2010-11-01 03:12:50
【问题描述】:

我目前正在设置身份验证系统。 我目前的布局是从$_POST 获取他的电子邮件,md5 他的密码,并根据他的电子邮件和密码检查数据库。 如果匹配,我使用session_start,并开始将数据存储在$_SESSION 变量中,如下所示:

 $_SESSION['uid'] = $uid;
 $_SESSION['first_name'] = $first_name;

并且在网站的每个页面上,我都会进行简单的检查

isset($_SESSION['uid']);

如果不是,则重定向到索引页面,如果是,则加载页面。

我这样做正确吗?这足够安全吗?有人伪造这些数据有多容易?

有人告诉我,我应该创建一个表格,其中包含用户的电子邮件和他的会话 ID,并使用它来管理事情......我变得相当困惑 - 这有什么帮助?

有人可以澄清一下吗?使用 PHP 会话管理身份验证的正确方法是什么?

谢谢。

【问题讨论】:

  • 您已经知道如何正确使用会话。然而,您正在尝试构建的是一个身份验证系统。这要复杂得多。你可以看看github.com/delight-im/PHP-Auth 并检查它的来源,看看它付出了很多努力和思考。

标签: php session cookies


【解决方案1】:

安全更新:截至 2017 年 10 月 23 日:此答案中的建议虽然具有历史意义,但完全不安全。永远不要在散列密码时使用 md5,因为它很容易被暴力破解。参见this answer 了解如何使用内置的password_* api 对密码进行哈希和验证。


我之前处理过登录/身份验证系统,我发现这种方法有几个缺点:

  • 你“md5他的密码,然后检查数据库”——这意味着如果一个人可以访问数据库,他可以找出谁拥有相同的密码!

附录(2015 年 9 月 19 日)* 看看这个link。它解释了所有基础知识、您可以采用的方法、为什么应该采用这些方法,还为您提供了示例 PHP 代码。如果太长看不下去,直接读到最后,抓码设置!

更好的方法:将username+password+email+salt的md5存储在数据库中,salt是随机的,与用户的记录一起存储。

  • 直接在会话变量中使用“uid”可能非常危险。考虑一下:我的朋友从我的浏览器登录,然后他离开了。我迅速检查了他的浏览器中设置了哪些 cookie,并破译了他的“uid”。现在我拥有他了!

更好的方法:在用户登录成功时生成一个随机的 sessionid,并将该 session ID 存储在$_SESSION[] 数组中。您还需要将 sessionid 与他的 uid 相关联(使用数据库或 memcached)。优点是:

  1. 您甚至可以将 sessionid 绑定到特定 IP,这样即使捕获到 sessionid 也不会被滥用
  2. 如果用户从其他位置登录,您可以使旧的 sessionid 无效。所以如果我朋友从他自己的电脑登录,我电脑上的 sessionid 会自动失效。

编辑:我一直手动使用 cookie 来处理我的会话。这有助于我更轻松地集成 Web 应用程序的 javascript 组件。将来您的应用中可能需要相同的功能。

【讨论】:

  • 如何生成随机会话 ID?使用 start_session?
  • 巧妙地应用了随机函数。我试过了,结果很好..在这里查看:jrharshath.qupis.com/random
  • @AwalGarg 是的。添加了一个附录以更安全的方式进行操作。
【解决方案2】:

我必须补充一点。如果您正在执行“MD5 密码,然后检查数据库”方法,这表明密码存储在单个 md5 哈希中。这不再是存储散列密码的标准方式。

我发现这个链接非常有用:http://www.itnewb.com/tutorial/Encrypting-Passwords-with-PHP-for-Storage-Using-the-RSA-PBKDF2-Standard

【讨论】:

    【解决方案3】:

    这样做没有错

    isset($_SESSION['uid']);
    

    会话数据不会传输给用户,而是存储在服务器上(或会话处理程序存储它的任何地方)。传递给用户的是会话ID,它只是PHP生成的随机字符串,当然可以被窃取,因为它是发送给用户的。

    应该清楚地指出,在数据库和用户会话中随机存储一个字符串,然后使用它来识别用户不会使会话更加安全,如果攻击者获得会话,他们仍然会受到损害用户。

    我们现在讨论的是session hijacking,您可能会认为您可以将 IP 地址存储在会话中,并检查来自请求的 IP 并完成它。然而,这通常不是那么简单,我最近在一个大型 Web 应用程序中将用户代理 + IP 地址的哈希存储在会话中,然后检查它们是否每次都匹配,对于 99% 的用户这工作得很好。然而,我们开始接到一些人的电话,他们发现他们不断被注销而没有任何解释。我们记录了会话劫持检查以查看发生了什么,发现这些人会进入一个 IP 并且他们的会话会在另一个 IP 上继续,这不是劫持尝试,而是与他们的代理服务器的方式有关工作,因此我们修改了我们的会话劫持代码以确定class of the IP address,并从那里找出IP地址的网络部分并仅存储IP地址的那些部分,这在会话劫持理论上可能稍微不安全来自同一个网络,但导致我们所有的误报都消失了。

    【讨论】:

      【解决方案4】:

      我不是 100% 同意这一点,但我认为如果有人真的想伪造会话是可能的!

      我认为将会话 ID 保存在表中是最安全的方法。

      我最近对此进行了一些研究,但我再次不确定,有兴趣了解最佳做法!

      这里有一些资源可供查看

      http://www.sitepoint.com/article/php-security-blunders/

      http://www.phpeasystep.com/workshopview.php?id=6

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-31
        • 2012-08-12
        • 1970-01-01
        相关资源
        最近更新 更多