如何防止用户通过点击“返回”按钮查看先前用户的信息

9

我正在开发一个使用servlet的Java web应用程序,为了防止用户点击后退按钮查看先前用户的信息,我有以下代码:

      protected void processRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
      {        
        HttpSession session=request.getSession(true);

        response.setContentType("text/html");
        response.setHeader("Cache-Control","no-cache,no-store");
        response.setDateHeader("Expires",0);
        response.setHeader("Pragma","no-cache");

        ......

        //    if (!User_Logged_In)
        session.invalidate();
      }

除此之外,我还在文件web/WEB-INF/web.xml中有以下代码:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
......
<filter>
  <filter-name>ResponseHeaderFilter</filter-name>
  <filter-class>ResponseHeaderFilter</filter-class>
  <init-param>
    <param-name>Cache-Control</param-name>
    <param-value>private,no-cache,no-store</param-value>
   </init-param>
  <init-param>
    <param-name>Pragma</param-name>
    <param-value>no-cache</param-value>
   </init-param>
  <init-param>
    <param-name>Expires</param-name>
    <param-value>0</param-value>
   </init-param>
</filter>

</web-app>

而ResponseHeaderFilter.java看起来像这样:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

public class ResponseHeaderFilter implements Filter
{
  FilterConfig fc;

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

    for (Enumeration e=fc.getInitParameterNames();e.hasMoreElements();)        // Set the provided HTTP response parameters
    {
      String headerName=(String)e.nextElement();
      response.addHeader(headerName,fc.getInitParameter(headerName));
    }
    chain.doFilter(req,response);                                              // Pass the request/response on
  }

  public void init(FilterConfig filterConfig)
  {
    this.fc=filterConfig;
  }

  public void destroy()
  {
    this.fc=null;
  }
}

到目前为止,它仍然不能正确工作。 返回按钮会弹出一个警告窗口,显示数据已过期,并询问用户是否要重新发布。 如果你选择“是”,它仍然会显示以前页面的信息。 我做错了什么? 有什么解决方法?
Frank
是的,我正在为公共场所的PC开发Web应用程序,如果用户B点击返回按钮,他可能会看到用户A的私人信息。
我试图使用servlet和session id,但如何做呢? 有示例代码吗?
我还尝试了以下内容:
<Html>
<Head>...</Head>
<Body onLoad=document.execCommand("ClearAuthenticationCache","false")>
......
<script type="text/javascript">
  // Clear current credentials : Requires IE6 SP1 or later
  // document.execCommand("ClearAuthenticationCache");
    document.execCommand("ClearAuthenticationCache","false");
  </script>
......
</Html>

它适用于IE,但不适用于Firefox。

13个回答

12

如何通过点击“返回”按钮使用户看到另一个用户的数据?你的用例是什么?它是为公共终端设计的吗?每个用户提交数据然后离开?如果是这样,将每个输入与唯一的会话ID相关联。在服务器上跟踪有效的会话ID。一旦输入被提交,从有效的ID中删除该会话ID。如果再次出现,则不显示信息。


我同意 - 听起来他正在尝试解决一个不应该存在的问题... 将会话作为单例运行或类似的方式? - GalacticCowboy

10
你的问题在于试图防止客户端查看自己计算机上的内容。你无法阻止他们查看浏览器缓存。你无法阻止他们禁用JavaScript(从而禁用你的脚本代码)。你也无法阻止他们使用不遵守"重新提交"约定的浏览器。这不是可以通过JavaScript或服务器端解决的问题。这也是为什么“破坏后退按钮”的方法受到谴责的一部分原因:它实际上没有解决任何问题。

实际上,您可以关闭缓存。大多数浏览器都会尊重此设置,但不能保证。 - sep332
正如我在这里的帖子中提到的那样,您可以关闭缓存,但是不同的用户代理可能会以不同的方式处理历史记录。HTTP规范对两者进行了区分,但并没有像定义缓存一样明确定义历史记录的概念。 - laz

3

破坏浏览器“后退”按钮是Web开发中的大忌。

但你可以在onload事件中尝试一些JavaScript代码,根据当前登录的会话刷新详细信息。


1
破解返回按钮只在单个会话中有效。例如,我不能打开一个新的浏览器窗口并点击“返回”按钮以返回我上次访问过的网站。 - sep332

2

看起来你真正的问题在于重新发布起作用。这可能是因为你:

  1. 信任浏览器而不是当前会话中的凭据,或者
  2. 没有检查当前会话是否被允许访问浏览器发送的键/标识符值所表示的数据

我建议,在用户登录后,您永远不要相信浏览器提交的用户名。最好使用类似于Spring Security这样的框架的安全服务,但如果没有这些服务,您可以依赖于HttpServletRequest.getUserPrincipal()

为了确保当前会话被允许访问数据,您可以使用由Spring Security等框架提供的访问控制列表机制,或在数据库查询中包含一个WHERE OWNER=?子句。


1

我不确定我是否完全理解了您的问题。您是否担心A人注销,B人从同一台电脑和浏览器实例登录,然后您想防止B人看到A人正在查看的内容?

如果是这样,每次页面加载时检查用户凭据应该就足够了。检查当前用户是否有权限查看请求的数据。


1

我不确定我正确理解了你的问题,但听起来好像你允许重新提交。

防止重复提交的一种方法是使用令牌。在表单和会话中放置一个随机令牌。在提交时检查提交的令牌是否与会话中的令牌匹配

  • 如果匹配,则用新的令牌替换会话中的令牌并处理请求
  • 否则停止处理请求)。

1
所有不同的浏览器在历史记录与缓存及可用的各种头部控制方式方面都有不同的行为和怪癖。Firefox 3与Firefox 2的工作方式不同,尽管使用缓存指令来防止它,但当用户单击后退按钮时,可能会重新显示潜在的敏感数据。最好的解决方法是使用一个不持续存在的会话cookie,并告知用户注销后需要关闭浏览器窗口,特别是在公共终端上。痛苦,我知道,但当前的浏览器和HTTP规范没有提供任何处理浏览器历史记录的机制。根据HTTP规范,历史记录可能会被用户代理以不同于缓存的方式处理。请参见RFC 2616《超文本传输协议--HTTP/1.1》中定义的13.13 历史记录列表以了解此问题及其原理。

0

我认为这不仅是一个编码问题,也是一个用户界面的挑战。除了采用任何反缓存技术之外,您还需要向用户明确表示,当他们完成操作时,必须点击一个大而明显的“注销”按钮(或等效按钮)。


0
如果这可能有所帮助。这适用于ASP,对于其他语言,请使用等效的解决方案。

0
如果您担心有人会看到先前页面中表单中的内容,您可以为“真实”帖子使用隐藏表单,并为用户使用一个仅用于显示的表单。当用户提交显示表单时,您将所有字段复制到隐藏表单中,清除显示表单,然后提交隐藏表单。
我同意其他人的观点-通过操作返回按钮来处理保护信息是一种不好的方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接