简体   繁体   English

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

[英]Correct way to manage sessions in PHP?

I'm currently setting up an authentication system. 我目前正在建立一个身份验证系统。 My current layout is to get his email from the $_POST , md5 his password, and check the database against his email and his password. 我目前的布局是从$_POST ,md5获取他的电子邮件密码,并根据他的电子邮件和密码检查数据库。 If it matches, I use session_start , and I start storing data in the $_SESSION variable, like so: 如果匹配,我使用session_start ,并开始在$_SESSION变量中存储数据,如下所示:

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

And on every page of the website, I would preform a simple check of 在网站的每一页上,我都会做一个简单的检查

isset($_SESSION['uid']);

if not, redirect to index page, if is, load the page. 如果没有,重定向到索引页面,如果是,则加载页面。

Am I doing this correctly? 我这样做了吗? Is this secure enough? 这足够安全吗? How easy is it for someone to forge that data? 有人伪造数据有多容易?

Someone told me that I should create a table, with the user's email, and his session-id and use that to manage things... I've become rather confused - how would this help? 有人告诉我,我应该创建一个表,用户的电子邮件,以及他的session-id并使用它来管理事情......我变得很困惑 - 这会有什么帮助?

Could someone clarify this? 有人可以澄清一下吗? What is the correct way to manage authentication with PHP sessions? 使用PHP会话管理身份验证的正确方法是什么?

Thanks. 谢谢。

Security update : as of 2017-10-23: The advice in this answer, while of historical significance, is completely insecure. 安全更新 :截至2017年10月23日:这个答案中的建议虽然具有历史意义,但却完全不安全。 One should never use md5 in hashing a password because it is so easily brute forced. 永远不应该使用md5来散列密码,因为它很容易被强制使用。 See this answer about how to use the built-in password_* api to hash and verify passwords. 请参阅此答案,了解如何使用内置的password_ * api来散列和验证密码。


I've dealt with login/authentication systems earlier, and I find several shortcomings in this method: 我之前已经处理过登录/身份验证系统,我发现这个方法有几个缺点:

  • you "md5 his password, and check the database" -- this means that if a person has access to the database, he can make out who has the same passwords! 你“md5他的密码,并检查数据库” - 这意味着,如果一个人有权访问数据库,他可以确定谁拥有相同的密码!

ADDENDUM (19 Sep 2015) * Look at this link . ADDENDUM(2015年9月19日)*请看这个链接 It explains all the basics, the approaches you could take, why you should take those approaches and also gives you sample PHP code. 它解释了所有基础知识,您可以采用的方法,为什么要采用这些方法,并为您提供示例PHP代码。 If it's too long to read, just go to the end, grab the code and get set! 如果它读的时间太长,只需到最后,抓住代码并设置好!

BETTER APPROACH : to store md5 of username+password+email+salt in the database, salt being random, and stored together with the user's record. 更好的方法 :在数据库中存储username+password+email+salt md5, 是随机的,并与用户的记录一起存储。

  • using the 'uid' directly in the session variables can be very risky. 在会话变量中直接使用'uid'可能会非常危险。 Consider this: my friend is logged on from my browser, and he leaves for a leak. 考虑一下:我的朋友从我的浏览器登录,他离开了。 I quickly check which cookies are set in his browser, and decipher his 'uid'. 我快速检查他的浏览器中设置了哪些cookie,并破译他的'uid'。 Now I own him! 现在我拥有他!

BETTER APPROACH : to generate a random sessionid when the user logs in successfully, and store that session ID in the $_SESSION[] array. 更好的方法 :在用户成功登录时生成随机会话ID,并将该会话ID存储在$_SESSION[]数组中。 You will also need to associate the sessionid with his uid (using the database, or memcached). 您还需要将sessionid与其uid相关联(使用数据库或memcached)。 Advantages are: 优点是:

  1. You can even bind a sessionid to a particular IP so that the sessionid can't be abused even if it is captured 您甚至可以将sessionid绑定到特定IP,以便即使捕获了sessionid也不会被滥用
  2. You can invalidate an older sessionid if the user logs on from another location. 如果用户从其他位置登录,则可以使较旧的sessionid无效。 So if my friend logs in from his own computer, the sessionid on my computer becomes invalid automatically. 因此,如果我的朋友从他自己的计算机登录,我计算机上的sessionid将自动变为无效。

EDIT: I've always used cookies manually for my session handling stuff. 编辑:我总是手动使用cookie来处理会话。 This helps me integrate the javascript components of my web apps more easily. 这有助于我更轻松地集成我的Web应用程序的JavaScript组件。 You may need the same in your apps, in the future. 将来,您的应用可能需要相同的功能。

There is nothing wrong with doing this 这样做没有错

isset($_SESSION['uid']);

The session data is not transmitted to the user, it's stored on the server (or wherever the session handler stores it). 会话数据不会传输给用户,而是存储在服务器上(或会话处理程序存储它的任何地方)。 What is transmitted to the user is the session id which is just a random string generated by PHP, this can be stolen of course because it's sent to the user. 传输给用户的是会话ID,它只是PHP生成的随机字符串,当然可以被盗,因为它被发送给用户。

It should be clearly noted that randomly storing a string in the database and the users session and then using that to identify the user does not make the session any more secure, if the attacker gets the session they are still going to have compromised the user. 应该清楚地注意到,在数据库中随机存储字符串和用户会话,然后使用它来识别用户不会使会话更安全,如果攻击者获得会话,他们仍然会破坏用户。

What we're discussing now is session hijacking , you may be thinking that you can just store the IP address in the session and check that with the IP coming from the request and be done with it. 我们现在讨论的是会话劫持 ,你可能会认为你可以只在会话中存储IP地址,并检查来自请求的IP并完成它。 However it's often not that simple, I got burned with this recently when on a large web application we were storing a hash of the User Agent + IP address in the session and then checking that they matched on each occasion, for 99% of the users this worked fine. 然而,它通常不是那么简单,我最近在大型Web应用程序中被烧毁,我们在会话中存储用户代理+ IP地址的哈希,然后检查它们在每种情况下匹配,对于99%的用户这工作得很好。 However, we started getting calls in from people who were finding that they were continually being logged out with no explanation. 然而,我们开始接听那些发现他们不断被注销而没有任何解释的人的电话。 We put logging on the session hijacking checks to see what was going on and found that these people would come in on one IP and their session would continue on another, this wasn't a hijacking attempt however it was to do with how their proxy server worked, as a result we amended our session hijacking code to ascertain the class of the IP address and from there figure out the network portion of the IP address and store just those parts of the IP address, this is slightly less secure in that session hijacking could theoretically come from inside the same network but caused all our false positives to go away. 我们记录了会话劫持检查以查看发生了什么,并发现这些人会进入一个IP并且他们的会话将继续在另一个IP上,这不是劫持尝试,但它与他们的代理服务器如何做因此,我们修改了会话劫持代码以确定IP地址类别,并从那里找出IP地址的网络部分并仅存储IP地址的那些部分,这在会话劫持中稍微不那么安全从理论上讲,它可能来自同一个网络,但却导致我们所有的误报都消失了。

I must add onto this. 我必须加上这个。 If you are doing the "MD5 the password, then check the database" method, this suggest that the password is stored in a single md5 hash. 如果您正在执行“MD5密码,然后检查数据库”方法,这表明密码存储在单个md5哈希中。 This is no longer a standard way of storing hashed passwords. 这不再是存储散列密码的标准方法。

I found this link very informative: http://www.itnewb.com/tutorial/Encrypting-Passwords-with-PHP-for-Storage-Using-the-RSA-PBKDF2-Standard 我发现此链接非常有用: http//www.itnewb.com/tutorial/Encrypting-Passwords-with-PHP-for-Storage-Using-the-RSA-PBKDF2-Standard

I am not 100% on this but I think that it is possible to forge the session if someone really wanted to! 我不是百分之百,但我认为如果有人真的想要有可能打造会议!

I think saving the session id in a table is the most secure way to do this. 我认为在表中保存会话ID是最安全的方法。

I have looked into this a little recently but again I'm not sure, interested to hear whats best practice! 我最近对此进行了一些调查,但我不确定,有兴趣听听最新的做法!

Here are a few resources to look at 以下是一些资源

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM