2011-08-18 76 views
2

我的登录系统目前的工作原理如下:如何实现隐式注销?

  1. 抓住用户的用户名和密码从POST形式。
  2. 检查数据库的用户名和salted +哈希密码。
  3. 如果认证成功,则生成一个长且随机的字母数字字符串。
  4. 将此字符串与用户名一起存储在MySQL以及$_SESSION变量中。
    • 这与仅将用户密码置于$_SESSION中相反。我觉得这样会让间谍软件进入并窃取用户的凭证。
  5. 在需要认证的每个网页(例如非敏感帐户设置,只有成员的地区,等等),检查$_SESSION用户名和串对那些存储在MySQL。
  6. 如果它们匹配,请继续并显示页面。否则,显示登录表单(?)
  7. 当用户明确注销时,从MySQL和$_SESSION中删除随机字符串。

我卡在的是如何处理当用户隐式注销。也就是说,当他/她关闭浏览器窗口而不点击网站上的任何“注销”按钮时。我很确定我仍然需要从MySQL中删除随机字符串,所以有人不能使用被盗的cookie来登录。但是,我怎么知道用户何时关闭浏览器窗口?

(“记住我”的功能是无关紧要的现在)

+0

你的随机字符串本质上就像一个会话。为什么你将它存储在'$ _SESSION'中而不是cookie?使用会话涉及文件系统访问,并在处理请求期间获得对会话文件的独占锁定,阻止它在调用请求之前(或直到调用session_write_close())之前处理其他请求) - 基本上一切都变慢。由PHP创建的会话ID已经与随机字符串几乎相同......您最好将其直接存储在cookie中。 – shesek

+0

让会话过期。 http://stackoverflow.com/questions/3068744/php-session-timeout – BlueDog

回答

3

我应该如何实施登录会话?

认证和会话管理是两个不同的东西,尽管它们紧密地绑在一起,你似乎也在谈论授权。

如果认证成功,则生成一个长且随机的字母数字字符串。

为什么? PHP已经生成了一个随机标识符(会话ID)。如果您想区分已验证/未验证的用户和/或识别哪个用户拥有当前会话,请将用户名/用户ID存储在会话中。

把用户的密码在$ _SESSION变量

为什么你想做到这一点 - 一旦你验证过的用户,你永远需要再次使用的密码。

检查$ _SESSION用户名和字符串对那些存储在MySQL

为什么?会话数据如何改变其他比通过你的代码?如果您怀疑您的服务器端代码可能被篡改,那么您的操作无关紧要,系统将变得不安全。

当用户明确地登出

...你明确地摧毁了会议。就这样。

当您从命题删除冗余没有必要隐式注销后进行清理。

BTW:有一些安全问题,你有没有在你的解决方案,特别是再生一个身份验证请求后的会话ID。

+0

+1,但我认为更好的解决方案是将他的随机字符串作为会话ID,方法是将其直接存储在cookie中,而不是使用PHP的本地会话处理,这是有问题的。看到我对这个问题的评论。 – shesek

0

你可以使用上onClose事件会调用Ajax,终止会话......从来没有尝试过,但它应该工作:

$(window).unload(function() { 
    // ajax to kill the session 
}); 
+0

我从来没有使用Ajax,我想避免添加更多的图层到网站。 – Maxpm

+0

您可以简单地使用'new Image()。src ='remove-session.php''向服务器发送请求。但是与执行'$ .get('remove-session.php')''没有多大区别......基本上,只是以某种方式向服务器发送请求并在处理请求时删除会话。 – shesek

+0

另外,如果您使用的是AJAX,请确保添加一些延迟或使请求同步。否则,浏览器可能会在服务器获取请求之前停止请求。您还可以添加'ignore_user_abort(TRUE)',这样即使浏览器关闭了连接,服务器也会继续处理请求 - 但它在浏览器在完全发送请求之前关闭连接的情况下不会有帮助。 – shesek