如何通过点击“返回”按钮来防止用户查看以前用户的信息[重复]

Posted

技术标签:

【中文标题】如何通过点击“返回”按钮来防止用户查看以前用户的信息[重复]【英文标题】:How to prevent a user from seeing previous users' info by hitting the "Back" button [duplicate] 【发布时间】:2010-09-20 04:26:03 【问题描述】:

我正在使用 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;
  

到目前为止,它仍然无法正常工作。后退按钮会弹出一个警告窗口,提示数据已过期,询问用户是否要重新发布。如果您选择是,它仍然会显示以前的页面信息。我究竟做错了什么?有什么解决办法?

弗兰克


是的,我正在为公共场所的 PC 开发网络应用程序,如果用户 B 点击后退按钮,他可能会看到用户 A 的私人信息。

我试图在 servlet 中使用会话 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。

【问题讨论】:

【参考方案1】:

Jeff Atwood 描述了一种防止 CSRF 和 XSRF 攻击的方法here。

您可以使用此技术来解决您的“用户看到他们不应该看到的内容”的问题。

【讨论】:

【参考方案2】:

当涉及到历史与缓存的关系以及可用于控制它的各种标头时,所有不同的浏览器都有不同的行为和怪癖。 Firefox 3 的工作方式与 Firefox 2 不同,尽管使用缓存指令来阻止它,但当用户单击后退按钮时会重新显示潜在的敏感数据。最好的解决方案是使用不持久的会话 cookie,并通知用户在注销后需要关闭浏览器窗口。特别是如果他们在公共终端。我知道这很痛苦,但是当前的浏览器产品和 HTTP 规范没有提供任何处理浏览器历史记录的机制。根据 HTTP 规范,历史可能与用户代理缓存不同。请参阅 RFC 2616 超文本传输​​协议 -- HTTP/1.1 中定义的13.13 History Lists,了解问题和基本原理。

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

我认为这既是一个用户界面挑战,也是一个编码问题。除了您使用的任何反缓存技术之外,您还需要让用户清楚地知道他们在完成后必须点击一个大而明显的“注销”按钮(或等效按钮)。

【讨论】:

【参考方案5】:

我不确定我是否正确理解了您的问题,但听起来您允许重新发布。

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

如果是,请将会话中的令牌替换为新令牌并处理请求 否则停止处理请求)。

【讨论】:

【参考方案6】:

我不能 100% 确定这是否可以解决您的问题,因为我不完全了解您将如何使用返回来获取其他用户的数据。但是,我知道对于我开发的网络应用程序,我会尝试专门使用Redirect After Post 以避免返回按钮和刷新重复的表单提交。

【讨论】:

【参考方案7】:

如果您担心有人看到前一页表单中的内容,您可以为“真实”帖子使用隐藏表单,并使用仅用于向用户显示的表单。当用户提交显示表单时,您将所有字段复制到隐藏表单,清除显示表单,然后提交隐藏表单。

我同意其他所有人的观点 - 摆弄后退按钮,这是处理保护信息的糟糕方式。

【讨论】:

【参考方案8】:

听起来你真正的问题是重新发布有效。那可能是因为你:

    信任来自浏览器而不是当前会话的凭据,或者 不检查当前会话是否允许访问由浏览器发送的键/标识符值表示的数据

我建议在用户登录后,您永远不要信任浏览器提交的用户名。理想情况下使用像Spring Security 这样的框架的安全服务,但如果没有它们,您可以依赖HttpServletRequest.getUserPrincipal()。

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

【讨论】:

【参考方案9】:

我在 .Net 中遇到了类似的问题。我将以下 javascript 添加到我的注销页面:

document.execCommand("ClearAuthenticationCache","false");

现在,如果您按下返回按钮,您需要再次进行身份验证。

【讨论】:

您是否考虑过恶意用户可以简单地关闭 Javascript?【参考方案10】:

您的问题是您试图阻止客户看到他或她自己的计算机上的内容。您不能阻止他们查看浏览器缓存。你不能阻止他们禁用 JavaScript(以及你的脚本代码)。您不能阻止他们使用不遵守您提到的“转发”约定的浏览器。

这不是一个可以用 JavaScript 或服务器端解决方案解决的问题。为什么“打破后退按钮”不受欢迎的部分原因是:它实际上并没有解决任何问题。

【讨论】:

其实可以关闭缓存。大多数浏览器都尊重这一点,但不能保证。 正如我在此处的帖子中提到的,您可以关闭缓存,但不同的用户代理可能会以不同的方式处理历史记录。 HTTP 规范对两者进行了区分,但并没有真正定义历史的概念,也没有定义缓存。【参考方案11】:

点击后退按钮如何让用户看到另一个用户的数据?你的用例是什么?它是为公共终端设计的,每个用户提交数据然后离开?在这种情况下,将每个输入与唯一的会话 ID 相关联。跟踪服务器中的有效会话 ID。提交输入后,从有效 ID 中删除该会话 ID。如果再次出现,则不要显示该信息。

【讨论】:

我同意 - 听起来他正在尝试解决一个不应该存在的问题...以单例或其他方式运行会话?【参考方案12】:

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

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

【讨论】:

【参考方案13】:

打破后退按钮是 Web 开发的一大罪过。

但您可以在 onload 中尝试一些 java 脚本,根据当前登录的会话刷新详细信息。

【讨论】:

断开后退按钮仅在单个会话中相关。例如,我无法打开一个新的浏览器窗口并点击“返回”按钮转到我上次访问的网站。

以上是关于如何通过点击“返回”按钮来防止用户查看以前用户的信息[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何防止用户“返回”但在 JSP 中注销后保留缓存?

通过在 L5 中点击浏览器上的后退按钮来防止注销后再次登录?

IOS - 如何防止后台按钮被点击?

阻止用户返回并查看以前提交的表单Rails

如何禁止用户连续点击一个按钮事件详细JS

前端js防止用户恶意操作,重复点击按钮事件