2012-05-09 294 views
11

我不希望用戶在註銷後單擊返回按鈕返回受保護頁面。在我的註銷代碼中,我沒有設置會話並重定向到登錄頁面。但是,我認爲瀏覽器正在緩存頁面,因此儘管會話從註銷中銷燬,它仍然可見。註銷後防止返回按鈕

我能夠通過不允許瀏覽器緩存

header("Cache-Control", "no-cache, no-store, must-revalidate")

避免這種情況,但這樣一來,我失去瀏覽器緩存的優勢。

請提出一個更好的實現方法。我覺得,必須有一種處理這個JavaScript客戶端的方式

+5

你不必禁用任何東西。如果他們回去,他們會被提供受限制頁面的緩存版本。如果他們試圖點擊它,則不會有效,因爲不會設置適當的會話。 –

+0

@ N.B。一個可能的解決方案可能不一定總是可用,因爲用戶可能在其顯示器上有敏感數據,然後退出。另一個來了(雖然工作站應該被鎖定;))並且按下並查看(雖然緩存)了以前用戶的數據。我們通常會添加一條提示用戶關閉瀏覽器的信息消息(以確保所有會話都已被清除)。這不一定是最好的方式,但至少您向用戶提供了有關潛在問題的信息。 – Juri

+0

如果一切都失敗了,便宜的修復方法是在註銷的頁面上出現「請出於安全原因關閉此窗口」消息。 – izb

回答

10

在PHP中實現而不是JavaScript。

在每個頁面的頂部,檢查用戶是否登錄如果不是,他們應該被重定向到一個登錄頁面:

<?php 
     if(!isset($_SESSION['logged_in'])) : 
     header("Location: login.php"); 
?> 

正如你提到的,在註銷,只需取消設置LOGGED_IN會話變量,並摧毀了會議:

<?php 
     unset($_SESSION['logged_in']); 
     session_destroy(); 
?> 

如果用戶點擊返現,沒有LOGGED_IN會話變量將是可用的,並且頁面將不會加載。

+19

我已經實施了這項技術。但按下按鈕實際上並不需要服務器。而是從瀏覽器緩存中呈現後臺頁面。因此它不會重定向到登錄頁面。 – piyush

+0

那麼問題是什麼?註銷後用戶無法與服務器交互,並且只有後退按鈕才能檢索他已經看到的數據。如果這些數據可能被其他人濫用,請注意用戶關閉窗口或使用匿名標籤,如果他不這樣做,那是他的錯。 – david

0

你可以在每個受限制的頁面上插入一個條件/函數,檢查是否設置了適當的會話變量。這樣,您可以打印頁面的兩個版本(一個用於有效用戶,一個用於重定向到登錄頁面)

+1

我已經實現了這一點。但它不會阻止用戶在點擊後退按鈕時呈現頁面,因爲它是從瀏覽器的緩存中呈現的。雖然,如果用戶刷新頁面或在頁面上執行任何操作,他將被重定向回登錄頁面。由於內頁中的個人信息可能很少,因此我想限制用戶在註銷後按下返回按鈕以查看以前的頁面。 – piyush

0

避免用戶返回並不是一個好理由,最重要的是不安全。

如果您在網站上進行的每個「管理員」操作之前測試用戶的會話,則應該沒問題,即使用戶點擊後退按鈕,看到緩存頁面並嘗試一些內容。

由於會話不再有效,「關聯某事」將返回一個錯誤。

相反,你應該專注於擁有一個真正安全的後臺。

1

我認爲你唯一的服務器端選項是禁止緩存。實際上,如果您正在使用JavaScript大量應用程序,因爲您的主要HTML可能只是一系列JS調用,然後即時生成視圖,這實際上並不糟糕。這樣大量的數據(JS MVC和核心代碼)被緩存,但實際的頁面請求不是。

要添加到下面粘貼的評論我建議在加載時添加一個小的AJAX調用,即使是緩存的頁面,它會跳轉到您的後端並檢查會話。如果沒有找到會話,它會將用戶重定向。這是客戶端代碼,當然不是一個安全的修復,但看起來更好。

您可以用

如果這些方法都失敗,將被註銷頁面上的「請關閉這個窗口,出於安全原因」的消息讓這一關你的良心一個廉價的修復。 - izb 2012年5月9日在8點36分

但像N.B.說

您不必禁用任何東西。如果他們回去,他們會被提供受限制頁面的緩存版本。如果他們試圖點擊它,則不會有效,因爲不會設置適當的會話。 - N.B. 5月9日'12 7:50

0

下面是一個簡單而快速的解決方案。

到登錄表單標記添加target="_blank"它顯示在不同的窗口的內容。然後註銷後只需關閉該窗口,後退按鈕問題(Safari瀏覽器)就解決了。

即使試圖使用歷史記錄也不會顯示頁面,而是重定向到登錄頁面。對於Safari瀏覽器而言,這很好,但對於Firefox等其他人,session_destroy();會照顧它。

0

您需要哪個loged在頁面中,使用setInterval每1000毫秒,並檢查wheather用戶登錄或不使用AJAX。如果用戶會話無效,請將其重定向到登錄頁面。

3

我面臨同樣的問題,花了整整一天搞清楚它, 最後糾正它,如下所示:

在登錄驗證腳本,如果用戶進行身份驗證設置一個會話值爲例說明如下:

$_SESSION['status']="Active"; 

然後在用戶配置文件腳本把下面的代碼片段:

<?php 

session_start(); 

if($_SESSION['status']!="Active") 
{ 
    header("location:login.php"); 
} 

?> 

上面的代碼是什麼只和ONL是, y如果$_SESSION['status']設置爲"Active"那麼只有它會轉到用戶配置文件,並且只有在用戶通過身份驗證後,此會話密鑰纔會被設置爲"Active" ... [注意否定['! 「在上面的代碼片段]

可能退出代碼應該如下:

{ 
    session_start(); 
    session_destroy(); 
    $_SESSION = array(); 
    header("location:login.php"); 
} 

希望這有助於... !!!

0

注意,雖然用戶無法更改復位會話數據和/或Cookie後話,他們仍然可以看到平常的信息訪問到登錄的用戶,因爲他們出現在最後一次訪問。這是由瀏覽器緩存頁面造成的。

你必須確保添加標題由登錄的用戶可訪問的每一頁上,告訴該數據是敏感的瀏覽器,他們不應該緩存後退按鈕腳本的結果。添加

header("Cache-Control: no-cache, must-revalidate"); 

注意:不是這個標題下的腳本的直接結果其他的其他元素,仍然會被緩存,你可以從中受益是很重要的。看到您逐漸加載頁面的一部分,並使用此標頭標記敏感數據和主HTML。

的答案表明,你重置$_SESSION全局變量的logged_in部分能達到採伐出來,但要注意,第一,你不需要破壞會話作爲PHP's session_destroy() documentation

注中提到:您不必從通常的代碼中調用session_destroy()。清理$ _SESSION數組而不是銷燬會話數據。

第二,最好不要破壞會話,因爲文檔中的下一個警告說明了。

另外,unset()是一個懶惰的功能;這意味着它將不會應用效果,直到下一次使用(部分)變量。在敏感的情況下使用賦值立即生效是一種很好的做法,主要是可能用於併發請求的全局變量。我建議你用這個代替:

$_SESSION['logged_in'] = null; 

並讓垃圾收集器收集它,同時它作爲登錄用戶無效。

最後,要完成解決方案,下面是一些功能:

<?php 
/* 
* Check the authenticity of the user 
*/ 
function check_auth() 
{ 
    if (empty($_SESSION['logged_in'])) 
    { 
     header('Location: login.php'); 
     // Immediately exit and send response to the client and do not go furthur in whatever script it is part of. 
     exit(); 
    } 
} 

/* 
* Logging the user out 
*/ 
function logout() 
{ 
    $_SESSION['logged_in'] = null; 
    // empty($null_variable) is true but isset($null_variable) is also true so using unset too as a safeguard for further codes 
    unset($_SESSION['logged_in']); 
    // Note that the script continues running since it may be a part of an ajax request and the rest handled in the client side. 
} 
0

添加在登錄HTML頁面腳本標籤中下面的代碼(或任何網頁時註銷後重定向到)

<script> 
history.pushState(null, null, document.title); 
window.addEventListener('popstate', function() { 
    history.pushState(null, null, document.title); 
}); 
</script> 

此腳本將在註銷後禁用後退按鈕。