2013-07-05 71 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