我正在构建一种PHP应用程序。我有一个登录表单,我在会话变量中存储了一个令牌,这个会话变量基本上告诉服务器用户在线(这个数据也存储在数据库中)。当登录表单显示时(新登录...或注销时,此代码清除 - 此处未显示代码)。我还将成功登录时将session_id()存储在数据库中。php:重新载入登录表单或重复登录
为防止2次会议是开放的(在同一个浏览器或不同的浏览器),我做2类型检查:
请问用户只登录后打开第二个选项卡,我对证此令牌和http referrer。如果令牌不为空(意味着某人已经登录)并且http referrer为空(意味着一个新的选项卡/窗口已被打开),我会回复一条错误消息(“您已经有一个打开的会话...”)。
用户在登录之前是否打开了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();
} ?>
现在,我在每个页面的顶部都有一个登录表单,并在结尾处有一个'exit();',只有在登录成功时才会跳过。你的意思是我应该创建登录页面作为一个独立的页面,才能正常工作? – webeno
你可能没有收到我以前的笔记...? – webeno
我已经实现了这个方法,它完美的工作,谢谢! – webeno