我正在構建一種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