Javascript 注销后防止后退按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10511893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Prevent back button after logout
提问by piyush
I don't want the user to go back to secured pages by clicking back button after logging out. In my logout code, I am unsetting the sessions and redirecting to login page.But, I think the browser is caching the page so it becomes visible despite the session being destroyed from logout.
我不希望用户在注销后通过单击后退按钮返回受保护的页面。在我的注销代码中,我取消设置会话并重定向到登录页面。但是,我认为浏览器正在缓存页面,因此尽管会话因注销而被破坏,它仍然可见。
I am able to avoid this by not allowing the browser to cache
我可以通过不允许浏览器缓存来避免这种情况
header("Cache-Control", "no-cache, no-store, must-revalidate")
header("Cache-Control", "no-cache, no-store, must-revalidate")
But this way I am loosing the advantage of Browser Caching.
但是这样我就失去了浏览器缓存的优势。
Please suggest a better way of achieving this. I feel, there must be a way of handling this by javascript client side
请提出更好的方法来实现这一目标。我觉得,javascript 客户端必须有一种方法来处理这个问题
回答by Jonathan Spiller
Implement this in PHP and not javascript.
在 PHP 而不是 javascript 中实现它。
At the top of each page, check to see if the user is logged in. If not, they should be redirected to a login page:
在每个页面的顶部,检查用户是否登录。如果没有,他们应该被重定向到登录页面:
<?php
if(!isset($_SESSION['logged_in'])) :
header("Location: login.php");
?>
As you mentioned, on logout, simply unset the logged_in session variable, and destroy the session:
正如您所提到的,在注销时,只需取消设置 login_in 会话变量,然后销毁会话:
<?php
unset($_SESSION['logged_in']);
session_destroy();
?>
If the user clicks back now, no logged_in session variable will be available, and the page will not load.
如果用户现在点击返回,则没有 login_in 会话变量可用,页面将不会加载。
回答by Tushar Kshirsagar
I was facing this same problem and spent whole day in figuring out it, Finally rectified it as follows:
我遇到了同样的问题,花了一整天的时间才弄清楚,最后纠正如下:
In login validation script if user is authenticated set one session value for instance as follows:
在登录验证脚本中,如果用户通过身份验证,请设置一个会话值,例如如下:
$_SESSION['status']="Active";
And then in User Profile script put following code snippet:
然后在用户配置文件脚本中放置以下代码片段:
<?php
session_start();
if($_SESSION['status']!="Active")
{
header("location:login.php");
}
?>
What above code does is, only and only if $_SESSION['status']
is set to "Active"
then only it will go to user profile , and this session key will be set to "Active"
only if user is authenticated... [Mind the negation [' ! '] in above code snippet]
上面的代码所做的是,仅当$_SESSION['status']
设置为"Active"
then only 它才会转到用户配置文件,并且此会话密钥将设置为"Active"
仅当用户通过身份验证时... [注意否定 [' !'] 在上面的代码片段中]
Probably logout code should be as follows:
大概注销代码应该如下:
{
session_start();
session_destroy();
$_SESSION = array();
header("location:login.php");
}
Hope this helps...!!!
希望这可以帮助...!!!
回答by Nenotlep
I think your only server side option is to disallow caching. This is actually not that bad if you are using a Javascript heavy application as your main HTML might only be a series of JS calls and the Views are then generated on the fly. That way the bulk of the data (JS MVC and core code) is cached but the actual page request isn't.
我认为您唯一的服务器端选项是禁止缓存。如果您使用的是 Javascript 密集型应用程序,这实际上并没有那么糟糕,因为您的主要 HTML 可能只是一系列 JS 调用,然后会即时生成视图。这样大部分数据(JS MVC 和核心代码)被缓存,但实际的页面请求不是。
To add to the comments pasted below I would suggest adding a small AJAX call during load time that fires even for cached pages that goes to your backend and checks the session. If not session is not found it would redirect the user away. This is clientside code and not a secure fix, sure, but looks nicer.
要添加到下面粘贴的评论中,我建议在加载时添加一个小的 AJAX 调用,即使对于进入后端并检查会话的缓存页面也会触发。如果没有找到会话,它将重定向用户。这是客户端代码而不是安全修复,当然,但看起来更好。
You could get this off your conscience with
你可以把这从你的良心上去掉
A cheap fix if all else fails would be a "Please close this window for security reasons" message on the logged out page. – izb May 9 '12 at 8:36
如果所有其他方法都失败了,一个廉价的修复方法是在注销页面上显示“出于安全原因请关闭此窗口”消息。– izb 2012 年 5 月 9 日 8:36
But like N.B. said
但就像NB说的
You don't have to disable anything. If they go back, they're served the cached version of the restricted page. If they try to click around it, nothing will work because the appropriate session won't be set. – N.B. May 9 '12 at 7:50
你不必禁用任何东西。如果他们返回,则会为他们提供受限页面的缓存版本。如果他们试图点击它,则没有任何效果,因为不会设置适当的会话。– NB 2012 年 5 月 9 日 7:50
回答by AntoBarn
Here's an easy and quick solution.
这是一个简单快捷的解决方案。
To the login form tag add target="_blank"
which displays content in a different window. Then after logout simply close that window and the back button problem (Safari browser) is solved.
在登录表单标签中添加target="_blank"
在不同窗口中显示内容的标签。然后注销后只需关闭该窗口即可解决后退按钮问题(Safari 浏览器)。
Even trying to use the history will not display the page and instead redirect to login page. This is fine for Safari browsers but for others such as Firefox the session_destroy();
takes care of it.
即使尝试使用历史记录也不会显示页面,而是重定向到登录页面。这对于 Safari 浏览器来说很好,但对于其他浏览器(例如 Firefox)session_destroy();
,它会处理它。
回答by swapnil shahane
the pages on which you required loged in, use setInterval
for every 1000 ms and check wheather user is logged in or not using ajax. if user session is invalid, redirect him to log in page.
您需要登录的页面setInterval
,每 1000 毫秒使用一次,并检查用户是否使用 ajax 登录。如果用户会话无效,则将他重定向到登录页面。
回答by Cunning
Note that although users can't change anything after resetting session data and/or cookie, they still may see usual information accessible to a logged in user as they appeared on the last visit. That is caused by browser caching the page.
请注意,尽管用户在重置会话数据和/或 cookie 后无法更改任何内容,但他们仍然可以看到登录用户可访问的常规信息,就像他们在上次访问时出现的一样。这是由浏览器缓存页面引起的。
You have to be sure to add the header on every page accessible by a logged in user, telling the browser that the data is sensitive and they should not cache the script result for the back button. It is important to add
您必须确保在登录用户可访问的每个页面上添加标题,告诉浏览器数据是敏感的,他们不应该缓存后退按钮的脚本结果。重要的是添加
header("Cache-Control: no-cache, must-revalidate");
Note that those other elements other than the immediate result of the script under this header, will still be cached and you can benefit from it. See that you gradually load parts of your page and tag sensitive data and the main HTML with this header.
请注意,除此标头下脚本的直接结果之外的其他元素仍将被缓存,您可以从中受益。看到您逐渐加载页面的一部分并使用此标题标记敏感数据和主 HTML。
As the answer suggests, unsetting the logged_in
portion of $_SESSION
global variable can achieve logging out, but be aware that first, you don't need to destroy session as mentioned in the PHP's session_destroy()
documentation
正如答案所暗示的那样,取消logged_in
设置$_SESSION
全局变量的部分可以实现注销,但请注意,首先,您不需要像PHP文档中提到的那样销毁会话session_destroy()
Note: You do not have to call session_destroy() from usual code. Cleanup $_SESSION array rather than destroying session data.
注意:您不必从通常的代码中调用 session_destroy()。清理 $_SESSION 数组而不是销毁会话数据。
And second, you better not to destroy the session at all as the next warning on the documentation explains.
其次,正如文档中的下一个警告所解释的那样,您最好不要破坏会话。
Also, unset()
is a lazy function; meaning that it won't apply the effect, until next use of the (part of the) variable in question. It is good practice to use assignment for immediate effect in sensitive cases, mostly global variables that may be used in concurrent requests. I suggest you use this instead:
另外,unset()
是一个懒惰的函数;这意味着它不会应用效果,直到下次使用相关的(部分)变量。在敏感情况下使用赋值立即生效是一种很好的做法,主要是可能在并发请求中使用的全局变量。我建议你改用这个:
$_SESSION['logged_in'] = null;
and let the garbage collector collects it, at the same time it is not valid as a logged in user.
并让垃圾收集器收集它,同时它作为登录用户无效。
Finally, to complete the solution, Here are some functions:
最后,为了完成解决方案,这里有一些功能:
<?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.
}
回答by Mashmoom
Here's an easy solution which I have used in my application.
这是我在我的应用程序中使用的一个简单的解决方案。
Add the below code inside script tag in the login HTML page (or whichever page it redirects to after logout)
在登录 HTML 页面(或注销后重定向到的任何页面)的 script 标签中添加以下代码
<script>
history.pushState(null, null, null);
window.addEventListener('popstate', function () {
history.pushState(null, null, null);
});
</script>
It will disable the back button. You will not be able to go back by clicking on the back button.
它将禁用后退按钮。您将无法通过单击后退按钮返回。
Note: Not tested on Safari.
注意:未在 Safari 上测试。
回答by CosminO
You could insert a condition/function on each restricted page, checking if the appropriate session variable is set or not. This way, you can print 2 versions of the page (one for the valid users, and one redirecting to the login page)
您可以在每个受限页面上插入一个条件/函数,检查是否设置了适当的会话变量。这样,您可以打印页面的 2 个版本(一个用于有效用户,一个重定向到登录页面)
回答by Cyril N.
Avoiding the user to go back is not a good reason and most of all not secure at all.
避免用户返回不是一个很好的理由,最重要的是根本不安全。
If you test the user's session before every "admin" action made on the website, you should be fine, even if the user hit the back button, sees the cached page and tries something.
如果您在网站上进行的每个“管理员”操作之前测试用户的会话,您应该没问题,即使用户点击后退按钮,看到缓存页面并尝试某些操作。
The "ties something" will return an error since the session is no longer valid.
由于会话不再有效,“绑定某事”将返回错误。
Instead, you should focus on having a really secured back office.
相反,您应该专注于拥有一个真正安全的后台。