我不希望用戶在註銷後單擊返回按鈕返回受保護頁面。在我的註銷代碼中,我沒有設置會話並重定向到登錄頁面。但是,我認爲瀏覽器正在緩存頁面,因此儘管會話從註銷中銷燬,它仍然可見。註銷後防止返回按鈕
我能夠通過不允許瀏覽器緩存
header("Cache-Control", "no-cache, no-store, must-revalidate")
避免這種情況,但這樣一來,我失去瀏覽器緩存的優勢。
請提出一個更好的實現方法。我覺得,必須有一種處理這個JavaScript客戶端的方式
我不希望用戶在註銷後單擊返回按鈕返回受保護頁面。在我的註銷代碼中,我沒有設置會話並重定向到登錄頁面。但是,我認爲瀏覽器正在緩存頁面,因此儘管會話從註銷中銷燬,它仍然可見。註銷後防止返回按鈕
我能夠通過不允許瀏覽器緩存
header("Cache-Control", "no-cache, no-store, must-revalidate")
避免這種情況,但這樣一來,我失去瀏覽器緩存的優勢。
請提出一個更好的實現方法。我覺得,必須有一種處理這個JavaScript客戶端的方式
在PHP中實現而不是JavaScript。
在每個頁面的頂部,檢查用戶是否登錄如果不是,他們應該被重定向到一個登錄頁面:
<?php
if(!isset($_SESSION['logged_in'])) :
header("Location: login.php");
?>
正如你提到的,在註銷,只需取消設置LOGGED_IN會話變量,並摧毀了會議:
<?php
unset($_SESSION['logged_in']);
session_destroy();
?>
如果用戶點擊返現,沒有LOGGED_IN會話變量將是可用的,並且頁面將不會加載。
你可以在每個受限制的頁面上插入一個條件/函數,檢查是否設置了適當的會話變量。這樣,您可以打印頁面的兩個版本(一個用於有效用戶,一個用於重定向到登錄頁面)
我已經實現了這一點。但它不會阻止用戶在點擊後退按鈕時呈現頁面,因爲它是從瀏覽器的緩存中呈現的。雖然,如果用戶刷新頁面或在頁面上執行任何操作,他將被重定向回登錄頁面。由於內頁中的個人信息可能很少,因此我想限制用戶在註銷後按下返回按鈕以查看以前的頁面。 – piyush
避免用戶返回並不是一個好理由,最重要的是不安全。
如果您在網站上進行的每個「管理員」操作之前測試用戶的會話,則應該沒問題,即使用戶點擊後退按鈕,看到緩存頁面並嘗試一些內容。
由於會話不再有效,「關聯某事」將返回一個錯誤。
相反,你應該專注於擁有一個真正安全的後臺。
我認爲你唯一的服務器端選項是禁止緩存。實際上,如果您正在使用JavaScript大量應用程序,因爲您的主要HTML可能只是一系列JS調用,然後即時生成視圖,這實際上並不糟糕。這樣大量的數據(JS MVC和核心代碼)被緩存,但實際的頁面請求不是。
要添加到下面粘貼的評論我建議在加載時添加一個小的AJAX調用,即使是緩存的頁面,它會跳轉到您的後端並檢查會話。如果沒有找到會話,它會將用戶重定向。這是客戶端代碼,當然不是一個安全的修復,但看起來更好。
您可以用
如果這些方法都失敗,將被註銷頁面上的「請關閉這個窗口,出於安全原因」的消息讓這一關你的良心一個廉價的修復。 - izb 2012年5月9日在8點36分
但像N.B.說
您不必禁用任何東西。如果他們回去,他們會被提供受限制頁面的緩存版本。如果他們試圖點擊它,則不會有效,因爲不會設置適當的會話。 - N.B. 5月9日'12 7:50
下面是一個簡單而快速的解決方案。
到登錄表單標記添加target="_blank"
它顯示在不同的窗口的內容。然後註銷後只需關閉該窗口,後退按鈕問題(Safari瀏覽器)就解決了。
即使試圖使用歷史記錄也不會顯示頁面,而是重定向到登錄頁面。對於Safari瀏覽器而言,這很好,但對於Firefox等其他人,session_destroy();
會照顧它。
您需要哪個loged在頁面中,使用setInterval
每1000毫秒,並檢查wheather用戶登錄或不使用AJAX。如果用戶會話無效,請將其重定向到登錄頁面。
我面臨同樣的問題,花了整整一天搞清楚它, 最後糾正它,如下所示:
在登錄驗證腳本,如果用戶進行身份驗證設置一個會話值爲例說明如下:
$_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");
}
希望這有助於... !!!
注意,雖然用戶無法更改復位會話數據和/或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.
}
添加在登錄HTML頁面腳本標籤中下面的代碼(或任何網頁時註銷後重定向到)
<script>
history.pushState(null, null, document.title);
window.addEventListener('popstate', function() {
history.pushState(null, null, document.title);
});
</script>
此腳本將在註銷後禁用後退按鈕。
你不必禁用任何東西。如果他們回去,他們會被提供受限制頁面的緩存版本。如果他們試圖點擊它,則不會有效,因爲不會設置適當的會話。 –
@ N.B。一個可能的解決方案可能不一定總是可用,因爲用戶可能在其顯示器上有敏感數據,然後退出。另一個來了(雖然工作站應該被鎖定;))並且按下並查看(雖然緩存)了以前用戶的數據。我們通常會添加一條提示用戶關閉瀏覽器的信息消息(以確保所有會話都已被清除)。這不一定是最好的方式,但至少您向用戶提供了有關潛在問題的信息。 – Juri
如果一切都失敗了,便宜的修復方法是在註銷的頁面上出現「請出於安全原因關閉此窗口」消息。 – izb