退出后防止用户看到以前访问过的安全页面


99

我要求最终用户在注销/退出后不能返回受限页面。但是目前,最终用户可以通过浏览器后退按钮,访问浏览器历史记录甚至通过在浏览器地址栏中重新输入URL来做到这一点。

基本上,我希望最终用户退出后不能以任何方式访问受限页面。我怎样才能做到最好?我可以使用JavaScript禁用后退按钮吗?


7
使用请求后获取模式。Google。

Answers:


137

可以也不应禁用浏览器的后退按钮或历史记录。这对用户体验不利。有JavaScript hack,但是它们不可靠,并且在客户端禁用JS时也无法使用。

您的具体问题是请求的页面是从浏览器缓存中加载的,而不是直接从服务器中加载的。这本质上是无害的,但确实会使最终用户感到困惑,因为他/他错误地认为它确实来自服务器。

您只需要指示浏览器不要缓存所有受限的JSP页面(因此,不仅是注销页面/动作本身!)。这样,浏览器被迫从服务器而不是从缓存请求页面,因此将执行服务器上的所有登录检查。您可以使用过滤器执行此操作,该过滤器在方法中设置必要的响应标头doFilter()

@WebFilter
public class NoCacheFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
        response.setDateHeader("Expires", 0); // Proxies.

        chain.doFilter(req, res);
    }

    // ...
}

这个地图Filterurl-pattern的兴趣,例如*.jsp

@WebFilter("*.jsp")

或者,如果您只想对受保护页面设置此限制,则应指定一个涵盖所有受保护页面的URL模式。例如,当它们全部位于文件夹中时/app,则需要指定的URL模式/app/*

@WebFilter("/app/*")

甚至,您可以与Filter检查已登录用户的状态相同地执行此工作。

测试前不要忘记清除浏览器缓存!;)

也可以看看:


2
有时这还不够,我记得遇到了这样的问题。浏览器只记住最后一页。但这可能是IE6,我不记得了:)
Bozho 2010年

3
@Bozho:您提供的标题集不完整,或者浏览器的页面仍在缓存中。
BalusC 2010年

1
@Chris:适用于Firefox和所有其他浏览器。您的问题是在其他地方引起的。也许您忘记清除某些缓存了?还是在错误的响应上设置了这些标头?
BalusC

@BalusC我创建了一个单独的Filter类来覆盖该doFilter()方法。当我按下注销按钮时,它将被重定向到一个servlet,在该servlet中我使会话无效。我不确定该doFilter()方法在这里如何发挥作用。你能告诉我如何实现吗?如图所示,遵循正确的步骤。谢谢。
2013年

对我来说很好。在sendRedirect(...)和之后都经过测试forward()
Hal50000

5

如果转发页面,“ URL模式”中的* .jsp将不起作用。尝试也包括您的servlet ..这将使您的应用程序免受后退按钮问题的影响。


2

在不禁用浏览器后退按钮的情况下,最简单的方法是将以下代码添加到page_load您不希望用户注销后返回的页面的事件中:

if (!IsPostBack)
    {
        if (Session["userId"] == null)
        {
            Response.Redirect("Login.aspx");
        }
        else
        {
        Response.ClearHeaders();
        Response.ClearContent();
        Response.Clear();
        Session.Abandon();
        Session.Remove("\\w+");
        Response.AddHeader("Cache-Control", "no-cache, no-store, max-age = 0, must-revalidate");
        Response.AddHeader("Pragma", "no-cache");
        Response.AddHeader("Expires", "0");
        }
    }

6
尽管您的答案很有用,但请发布与所选OP编程语言相关的答案。您的C#解决方案对OP的Java EE项目无济于事。
Buhake Sindi

0

您可以尝试告诉浏览器不要缓存主页(使用适当的标头-Expires,Cache-Control,Pragma)。但是不能保证它能正常工作。您可以做的是在页面加载时对服务器进行Ajax调用,以检查用户是否已登录,如果没有登录,则重定向。


13
但是,如果一个坏主意禁用了JavaScript,那么它将无法正常工作,尽管如此,他仍然会看到该页面。
acme

0

正确的方法是添加

Vary: Cookie

安全页面上的标题。用户注销后,清除其会话cookie。然后,当他们注销后导航回去时,浏览器缓存将丢失。这还具有不完全克服缓存的优点。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.