在 PHP 中管理会话的正确方法?

2022-08-30 12:40:50

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

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

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

isset($_SESSION['uid']);

如果没有,请重定向到索引页,如果是,则加载该页。

我这样做是否正确?这是否足够安全?对于某人来说,伪造这些数据有多容易?

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

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

谢谢。


答案 1

安全更新:截至 2017-10-23:此答案中的建议虽然具有历史意义,但完全不安全。永远不应该使用md5来散列密码,因为它很容易被暴力破解。请参阅此答案,了解如何使用内置的 password_* API 对密码进行哈希处理和验证。


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

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

附录 (2015年9月19日) *查看此链接。它解释了所有基础知识,您可以采取的方法,为什么应该采用这些方法,并为您提供了示例PHP代码。如果太长而无法阅读,只需转到末尾,获取代码并设置!

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

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

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

  1. 您甚至可以将会话 ID 绑定到特定 IP,以便即使捕获会话 ID 也不会被滥用
  2. 如果用户从其他位置登录,则可以使较旧的会话 ID 失效。因此,如果我的朋友从他自己的计算机登录,我计算机上的会话ID会自动失效。

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


答案 2

这样做没有错

isset($_SESSION['uid']);

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

应该清楚地注意的是,在数据库和用户会话中随机存储一个字符串,然后使用它来识别用户并不能使会话更加安全,如果攻击者获得会话,他们仍然会破坏用户。

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


推荐