防止用户在注销后看到以前访问过的安全页面

发布于 2024-10-02 22:04:43 字数 166 浏览 11 评论 0原文

我的要求是最终用户在注销/注销后不应返回受限页面。但目前,最终用户可以通过浏览器后退按钮、访问浏览器历史记录,甚至在浏览器地址栏中重新输入 URL 来完成此操作。

基本上,我希望最终用户在注销后不能以任何方式访问受限页面。我怎样才能最好地实现这一目标?我可以使用 JavaScript 禁用后退按钮吗?

I have the requirement that the end user should not be able to go back to the restricted page after logout/sign out. But currently the end user is able to do that by the browser back button, visiting browser history or even by re-entering the URL in browser's address bar.

Basically, I want that the end user should not be able to access the restricted page in any way after sign out. How can I achieve this the best? Can I disable the back button with JavaScript?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

凉城已无爱 2024-10-09 22:04:43

可以但不应该禁用浏览器后退按钮或历史记录。这对用户体验很不利。有一些 JavaScript hack,但它们并不可靠,而且当客户端禁用 JS 时它们也不起作用。

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

您只需指示浏览器缓存所有受限制的JSP 页面(因此不仅仅是注销页面/操作本身!)。这样,浏览器被迫从服务器而不是从缓存请求页面,因此服务器上的所有登录检查都将被执行。您可以使用 Filter 来设置 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);
    }

    // ...
}

将此Filter映射到感兴趣的url-pattern上,例如*.jsp

@WebFilter("*.jsp")

或者,如果您只想将此限制放在安全页面上,那么您应该指定一个涵盖所有这些安全页面的 URL 模式。例如,当它们都在文件夹 /app 中时,则需要指定 /app/* 的 URL 模式。

@WebFilter("/app/*")

更重要的是,您可以在检查登录用户是否存在的同一个Filter 中完成这项工作。

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

另请参阅:

You can and should not disable the browser back button or history. That's bad for user experience. There are JavaScript hacks, but they are not reliable and will also not work when the client has JS disabled.

Your concrete problem is that the requested page is been loaded from the browser cache instead of straight from the server. This is essentially harmless, but indeed confusing to the enduser, because s/he incorrectly thinks that it's really coming from the server.

You just need to instruct the browser to not cache all the restricted JSP pages (and thus not only the logout page/action itself!). This way the browser is forced to request the page from the server instead of from the cache and hence all login checks on the server will be executed. You can do this using a Filter which sets the necessary response headers in the doFilter() method:

@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);
    }

    // ...
}

Map this Filter on an url-pattern of interest, for example *.jsp.

@WebFilter("*.jsp")

Or if you want to put this restriction on secured pages only, then you should specify an URL pattern which covers all those secured pages. For example, when they are all in the folder /app, then you need to specify the URL pattern of /app/*.

@WebFilter("/app/*")

Even more, you can do this job in the same Filter as where you're checking the presence of the logged-in user.

Don't forget to clear browser cache before testing! ;)

See also:

时光瘦了 2024-10-09 22:04:43

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

*.jsp in Url Pattern won't work if you forward a page. Try to include your servlet too.. that will make your application secure from this back button problem.

小巷里的女流氓 2024-10-09 22:04:43

在不禁用浏览器后退按钮的情况下执行此操作的最简单方法是将以下代码添加到您不希望用户在注销后返回的页面的 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");
        }
    }

The simplest way to do it without disabling the browser back buton is by adding this code to the page_load event for the page that you don't want the user to go back to after logging out:

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");
        }
    }
悟红尘 2024-10-09 22:04:43

正确的方法是在

Vary: Cookie

受保护的页面上添加标头。当用户注销时,清除其会话 cookie。然后,当他们注销后返回时,浏览器缓存将丢失。这还有一个好处就是不完全击败缓存。

The correct way to do this is to add the

Vary: Cookie

header on secured pages. When the user logs out, clear their session cookie. Then, when they navigate back after logging out, the browser cache will miss. This also has the benefit of not completely defeating caching.

云之铃。 2024-10-09 22:04:43

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

You can try telling the browser not to cache the homepage (using the appropriate headers - Expires, Cache-Control, Pragma). But it is not guaranteed to work. What you can do, is make an ajax call to the server on page load to check if the user is logged, and if not - redirect.

并安 2024-10-09 22:04:43

实现过滤器的另一种方法是在所有受保护的 JSP 或所有路径上设置“无缓存”过滤器。如果应用程序很小,并且您只想为特定页面自定义此属性,这可能是一个好主意。我们可以在每个不应缓存的安全 JSP 上添加以下 Java 片段:

<%
  response.addHeader("Pragma", "no-cache");
  response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  response.setDateHeader("Expires", 0);
%>

如果不在 JSP 上,这也可以在定义路由的控制器中使用,并为“HttpServletResponse”对象设置标头。

An alternative to implementing a Filter is to set a 'no-cache' filter on all the secured JSPs, or on all paths. This may be a good idea if the application is small, and if you would like to customize this property for a specific pages only. We can add the following Java snippet on every secured JSP that should not be cached:

<%
  response.addHeader("Pragma", "no-cache");
  response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  response.setDateHeader("Expires", 0);
%>

If not on JSP, this could also be used in Controllers where routing is defined and set the headers for the 'HttpServletResponse' object.

泛泛之交 2024-10-09 22:04:43

对我来说,问题是,我不想在所有页面上设置标题,所以我只是在单击注销时在页面上设置此标题,它会清除与网站相关的所有内容:)

// Removes all site data
response.setHeader ("Clear-Site-Data", "\"cache\"");

请在此处阅读更多相关信息:
https://developer.mozilla.org/ en-US/docs/Web/HTTP/Headers/Clear-Site-Data

For me the problem was , I didn't want to set headers on all pages , so I just set this header on page when logout is clicked and it clears everything related to the site :)

// Removes all site data
response.setHeader ("Clear-Site-Data", "\"cache\"");

Please read more about it over here :
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文