我目前正在建立一个身份验证系统.我目前的布局是从$_POST
他的密码中获取他的电子邮件,并根据他的电子邮件和密码检查数据库.如果它匹配,我使用session_start
,并开始在$_SESSION
变量中存储数据,如下所示:
$_SESSION['uid'] = $uid; $_SESSION['first_name'] = $first_name;
在网站的每一页上,我都会做一个简单的检查
isset($_SESSION['uid']);
如果没有,重定向到索引页面,如果是,则加载页面.
我这样做了吗?这足够安全吗?有人伪造数据有多容易?
有人告诉我,我应该创建一个表,用户的电子邮件,以及他的session-id并用它来管理事情......我变得相当困惑 - 这会有什么帮助?
有人可以澄清一下吗?使用PHP会话管理身份验证的正确方法是什么?
谢谢.
安全更新:截至2017年10月23日:这个答案中的建议虽然具有历史意义,但却完全不安全.永远不应该使用md5来散列密码,因为它很容易被强制使用.请参阅此答案,了解如何使用内置的password_*api来散列和验证密码.
我之前已经处理过登录/身份验证系统,我发现这个方法有几个缺点:
你"md5他的密码,并检查数据库" - 这意味着,如果一个人有权访问数据库,他可以确定谁拥有相同的密码!
ADDENDUM(2015年9月19日)*请看这个链接.它解释了所有基础知识,您可以采用的方法,为什么要采用这些方法,并为您提供示例PHP代码.如果它读的时间太长,只需到最后,抓住代码并设置好!
更好的方法:将md5存储username+password+email+salt
在数据库中,盐是随机的,并与用户的记录一起存储.
直接在会话变量中使用'uid'可能会非常危险.考虑一下:我的朋友从我的浏览器登录,他离开了.我快速检查他的浏览器中设置了哪些cookie,并破译他的'uid'.现在我拥有他!
更好的方法:在用户成功登录时生成随机会话ID,并将该会话ID存储在$_SESSION[]
数组中.您还需要将sessionid与其uid相关联(使用数据库或memcached).优点是:
您甚至可以将sessionid绑定到特定IP,以便即使捕获了sessionid也不会被滥用
如果用户从其他位置登录,则可以使较旧的sessionid无效.因此,如果我的朋友从他自己的计算机登录,我计算机上的sessionid将自动变为无效.
编辑:我总是手动使用cookie来处理会话.这有助于我更轻松地集成我的Web应用程序的JavaScript组件.将来,您的应用可能需要相同的功能.
这样做没有错
isset($_SESSION['uid']);
会话数据不会传输给用户,而是存储在服务器上(或会话处理程序存储它的任何地方).传输给用户的是会话ID,它只是PHP生成的随机字符串,当然可以被盗,因为它被发送给用户.
应该清楚地注意到,在数据库中随机存储字符串和用户会话,然后使用它来识别用户不会使会话更安全,如果攻击者获得会话,他们仍然会破坏用户.
我们现在讨论的是会话劫持,你可能会认为你可以只在会话中存储IP地址,并检查来自请求的IP并完成它.然而,它通常不是那么简单,我最近在大型Web应用程序中被烧毁,我们在会话中存储用户代理+ IP地址的哈希,然后检查它们在每种情况下匹配,对于99%的用户这工作得很好.然而,我们开始接到那些发现他们不断被注销而没有解释的人的电话.我们记录了会话劫持检查以查看发生了什么,并发现这些人会进入一个IP并且他们的会话将继续在另一个IP上,这不是劫持尝试,但它与他们的代理服务器如何做因此,我们修改了会话劫持代码以确定IP地址的类别,并从那里找出IP地址的网络部分并仅存储IP地址的那些部分,这在会话劫持中稍微不那么安全从理论上讲,它可能来自同一个网络,但却导致我们所有的误报都消失了.