2013-07-05 72 views
0

我正在构建一种PHP应用程序。我有一个登录表单,我在会话变量中存储了一个令牌,这个会话变量基本上告诉服务器用户在线(这个数据也存储在数据库中)。当登录表单显示时(新登录...或注销时,此代码清除 - 此处未显示代码)。我还将成功登录时将session_id()存储在数据库中。php:重新载入登录表单或重复登录

为防止2次会议是开放的(在同一个浏览器或不同的浏览器),我做2类型检查:

  1. 请问用户只登录后打开第二个选项卡,我对证此令牌和http referrer。如果令牌不为空(意味着某人已经登录)并且http referrer为空(意味着一个新的选项卡/窗口已被打开),我会回复一条错误消息(“您已经有一个打开的会话...”)。

  2. 用户在登录之前是否打开了2个选项卡,我检查了此令牌以及数据库中当前session_id()和session_id()。如果令牌在那里(意味着某人已经登录)并且数据库和当前session_id()是相同的(意味着我们仍然在同一浏览器中),我回显一条错误消息(“您已经有一个打开的会话.. “)。 session_id()在这里会有所不同,这意味着我们在另一个浏览器中,我也在检查这个。

我试图同时阻止用户重新发布登录表单,也就是说,我希望他们避免在登录后立即点击重新加载。

问题:
通过以上的设置,如果我点击重载,服务器会认为这是第二次浏览器选项卡登录(上述情况#2),因为该令牌将成为那里的SESSION_ID()将成为也一样,所以它会回显错误信息(“你已经有一个开放的会话......”)。

有没有办法结合起来,并确保登录表单重新加载没有任何反应?

的代码看起来是这样的(我试图剥夺这一关的不必要的代码,对不起,如果不是100%正确的):

<?php function LoginForm() { 
$_SESSION['token'] = ''; ?> 
<form action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']); ?>" method="post"> 
    Please enter your login details</div><br /> 
    Login ID<br /> 
    <input type="text" name="userid" /><br /><br />    
    Password<br /> 
    <input type="password" name="password" /><br /><br /> 
    <input type="submit" name="login" value="Login" /> 
</form> 
<?php } 

if (!empty($token_in_DB) AND !isset($_SERVER['HTTP_REFERER'])) { 
    echo "You are already logged in on another tab/window"; 
    exit(); 
} elseif (isset($_POST['login'])) { 
if (!empty($token_in_DB)) { 
    if ($session_in_DB == session_id()) { 
      echo "You are already logged in on another tab/window"; 
      exit(); 
    } else { 
      echo "You are already logged in on another browser/computer"; 
      exit(); 
      } 
    } elseif (/* password is ok */) {  
     // login 
     // set token session variable 
     // add token to db 
    } 
} elseif (empty($_SESSION['token'])) { 
    LoginForm(); 
} ?> 

回答

2

我想,在同一时间,阻止用户重新登录 登录表单,这意味着,我希望他们在登录后不要点击重新加载登录表 。

为了防止发生这种情况,您应该遵循POST-Redirect-GET模式,并在成功POST后始终重定向。即,如果登录成功,将它们重定向到启动页面或主页等。

其次,如果用户登录并通过另一个标签浏览,他或她将具有与第一个标签相同的会话ID 。这是除非他们已经打开一个新的隐私浏览/隐身窗口或他们正在利用代理。

+0

现在,我在每个页面的顶部都有一个登录表单,并在结尾处有一个'exit();',只有在登录成功时才会跳过。你的意思是我应该创建登录页面作为一个独立的页面,才能正常工作? – webeno

+0

你可能没有收到我以前的笔记...? – webeno

+0

我已经实现了这个方法,它完美的工作,谢谢! – webeno