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

我目前正在build立一个authentication系统。 我目前的布局是从$_POST ,他的密码MD5他的电子邮件,并检查数据库对他的电子邮件和他的密码。 如果匹配,我使用session_start ,并开始将数据存储在$_SESSIONvariables中,如下所示:

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

并在网站的每一页上,我会做一个简单的检查

 isset($_SESSION['uid']); 

如果没有,则redirect到索引页面,如果是,则加载页面。

我正确地做这个? 这安全吗? 有人伪造这些数据有多容易?

有人告诉我,我应该创build一个表,用户的电子邮件,他的会话ID,并用它来pipe理的事情…我变得相当困惑 – 这将如何帮助?

有人能澄清这一点吗? 用PHP会话pipe理身份validation的正确方法是什么?

谢谢。

安全更新 :截至2017年10月23日:这个答案的build议虽然具有历史意义,但是完全没有保证。 一个人不应该使用md5来散列密码,因为它很容易暴力破解。 查看关于如何使用内置password_ * api来散列和validation密码的答案 。


我已经处理了login/authentication系统,我发现这种方法的几个缺点:

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

附录(2015年9月19日)*请看这个链接 。 它解释了所有的基本知识,你可以采取的方法,为什么你应该采取这些方法,也给你示例PHP代码。 如果阅读时间过长,只要到最后,抓住代码并设置!

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

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

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

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

编辑:我一直使用cookies手动处理我的会话的东西。 这有助于我更轻松地集成我的Web应用程序的JavaScript组件。 未来,您的应用中可能需要相同的内容。

这样做没有错

 isset($_SESSION['uid']); 

会话数据不会传输给用户,它存储在服务器上(或会话处理程序存储的任何地方)。 传给用户的是session id,它只是一个由PHP生成的随机string,当然可能是因为它被发送给用户而被盗用。

应该清楚地注意到,在数据库和用户会话中随机存储一个string,然后使用它来标识用户不会使会话更加安全,如果攻击者得到会话,他们仍然会损害用户。

我们现在正在讨论的是会话劫持 ,你可能会认为你可以在会话中存储IP地址,并检查来自请求的IP,并用它来完成。 然而,通常情况并不那么简单,最近我在一个大型Web应用程序中被烧毁,我们在会话中存储了User Agent + IP地址的散列,然后检查它们是否匹配,对于99%的用户这工作得很好。 但是,我们开始接到来自人们的电话,他们发现他们不断被注销,没有任何解释。 我们在会话劫持检查上看到发生了什么事情,并发现这些人会进入一个IP,他们的会话会继续在另一个,这不是一个劫持的尝试,但它是如何做他们的代理服务器因此,我们修改了会话劫持代码,以确定IP地址的类别,并从那里计算出IP地址的networking部分并存储IP地址的这些部分,这在会话劫持方面稍微不安全理论上可以来自同一个networking内部,但是我们所有的误报都会消失。

我必须加上这个。 如果你正在做“MD5的密码,然后检查数据库”的方法,这表明密码存储在一个单一的MD5散列。 这不再是存储散列密码的标准方式。

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

我不是100%的,但是我认为如果有人真的想要这样做,那么就有可能伪造会议!

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

我最近看了一下这个,但是我不确定,有兴趣听听最佳做法!

这里有几个资源来看看

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

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