PHP登录系统

时间:2009-09-07 01:54:43

标签: php security session login

我正在使用PHP为Web应用程序创建登录系统。我的问题是,仅在当前会话中存储用户登录信息是否安全?例如,如果名为John的用户成功登录到我的站点,我可以只存储$ _SESSION ['Username'] ='John'和$ _SESSION ['LoggedIn'] = 1然后检查$ _SESSION ['LoggedIn']在每页上等于1以验证用户是否实际登录?或者有更好的方法吗?我不知道这可能导致我的头脑中出现任何问题,但我想确保我不会在我的网站上留下一个可能导致问题的大洞。

另外,我在数据库中存储了用户密码+ salt的md5哈希值,而不是它们的实际字符串密码,这样就不用担心了。

如果您需要更多信息或者不清楚,请与我们联系。谢谢!

6 个答案:

答案 0 :(得分:9)

这是一种非常合理的方法。您的访问者将永远无法编辑您服务器上的会话数据(除非服务器本身不安全,在这种情况下任何公平的游戏都是如此),因此会话中的LoggedIn = 1值非常安全。

但是,请记住一个访问者劫持另一个访问者的会话(通过窃取会话密钥)的风险。帮助防止这种情况的一种方法是将访问者的IP地址(来自$_SERVER['REMOTE_ADDR'])存储在会话中,然后在以后的请求中确认它没有更改。

答案 1 :(得分:3)

需要考虑许多风险:

  1. 会话劫持:这是有人窃取用户的cookie并伪装成他们的地方。有些人会建议使用IP过滤来解决这个问题,但这可能会产生尴尬的副作用。人们使用来自移动设备或用于工作,家庭和wifi热点的笔记本电脑上的网站,还有其他IP地址可能发生变化的情况。所以我的建议只针对高度敏感网站(例如网上银行);
  2. 您的网站遭到妥协:在这种情况下,用户无论如何都可以访问您的数据库,因此在会话中存储身份验证信息不会有额外的风险。通过向数据库发出UPDATE语句,他们可以轻松地改变他们的身份;
  3. 共同托管网站受到妥协:如果您使用共享托管,一个完全不相关的网站可能会让您面临风险(有或没有此方案),因为一堆网站都在运行相同的Apache实例,因此可以访问彼此的文件(虽然很难弄清楚他们属于哪个网站)。因此,如果您从未听说过的网站遭到入侵,则会影响您的网站;
  4. 共同托管网站是恶意的:类似于(3),但威胁是内部威胁,但在其他方面类似。
  5. 所以我说它很好(受(2)影响),但要注意风险。至少遵循这些最佳实践:

    1. 绝不存储未加密的密码;
    2. 使用强散列算法(首选SHA1或至少MD5);
    3. 确保身份验证Cookie在某个时刻到期。多长时间取决于您的网站。可能是一周或两周或一两个小时不活动或两者兼而有之。

答案 2 :(得分:1)

考虑SHA1或更强的哈希而不是MD5。不过,你在腌制它,这很好。

回到你的问题:是的,没关系。但是,请采取措施确保会话不被劫持。维基百科actually has a fairly good article on it

在我编写的大多数系统中,我都包含了验证远程IP没有改变的逻辑。您也可以将其存储在会话中,因为会话变量不会传递给用户(仅会话ID)。如果你真的想要发挥创意,可以添加其他支票 - 用户代理,什么不支持。

您还必须考虑会话攻击。检查推荐人。如果你有一个灾难性的操作,让我们把它称为DeleteMyAccount的POST,我可以写一个表单提交加javascript来点击不相关网站上的论坛帖子中的DeleteMyAccount,指望该会话出现在用户的信息中。

答案 3 :(得分:0)

听起来不错;你可能想考虑设置一个到期时间(所以如果有人离开并让浏览器打开,他们就不会危险)。

答案 4 :(得分:0)

总的来说,你肯定是在正确的轨道上。我建议您在会话中为用户使用ID而不是用户名,因为ID是代码中更好的唯一引用。

此外,md5不再被认为足够强大,无法进行密码散列:它太快而无法散列,并且您不希望检查攻击者是否需要反复运行(而真正的用户只需要这样做一次)。我希望我能找到参考,但前沿的智慧是做很多轮的前沿散列算法,比如sha512。

答案 5 :(得分:0)

您可以使用COOKIE代替SESSION变量。你可以按照

设置COOKIE

setcookie('ID',$ variable,time()+ 8 * 60 * 60);

您必须了解SQL注入。当您插入或更新用户文本框相关的数据库时,请注意SQL注入。通过htmlentities()函数插入/更新您的值。