真是一切都逃不过session,看了DZ的formhash;struts token什么啊,就是个session,安全级别比验证码还低。
看看别人的分析有益身心啊,看之,目前来讲一切都逃不过session
预期达到目标:
1、当用户进行的是Refresh/Reload/Back/Forward操作、以及先Back再Submit操作时,仅仅是reloading先前的结果页。
2、当用户重复提交同一个任务操作时,后台服务接收并处理第一次提交的任务,后面提交不起作用(不转向也不提示)。
3、该功能具有公用性。
基本形成思路:
1、在basic filter中实现公用性
if(true){//问题1:如何确定是否为重复提交
...
chain.doFilter(request,response);
}else{
//问题2:如何实现不转向、不提示也不显示空白页
}
2、网上资料概括
a、提交表单后按钮变灰/隐藏提交按钮
b、在js里设置全局变量,提交后修改该变量的值,依据变量的值判断是否重复提交
var flag=true;
function checkForm(){
if (flag==false){
return;
}
flag=false;
document.form1.submit();
}
c、struts (webwork没有找到这个资料)
//验证事务控制令牌,<html:form >会自动根据session中标识生成一个隐含input代表令牌,防止两次提交
在action中:
//<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae">
if (!isTokenValid(request))
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.transaction.token"));
resetToken(request); //删除session中的令牌
action有这样的一个方法生成令牌华
protected String generateToken(HttpServletRequest request) {
HttpSession session = request.getSession();
try {
byte id[] = session.getId().getBytes();
byte now[] =
new Long(System.currentTimeMillis()).toString().getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(id);
md.update(now);
return (toHex(md.digest()));
} catch (IllegalStateException e) {
return (null);
} catch (NoSuchAlgorithmException e) {
return (null);
}
}
d、用户使用浏览器时,可以经常使用向后的按钮,因此就有可能重复提交一个他们已经提交过的form,这样就会带来一个重复事务处理的问题。同样,一个用户也可能在接收到一个确认的页面之前按下停止的按钮,接着再次提交同一个form。对于这些情况,我们都想跟踪并且禁止这些重复的提交,我们可以使用一个控制servlet来提供一个控制点,以解决这个问题。
同步记号(Synchronizer (or Dvu) Token)
这个策略是为了解决重复的form提交问题。一个同步的记号被设置在一个用户的Session中,并且包含在返回到客户的每一个form中。当form被提交时,form中的同步标记就和Session中的同步标记作对比。在form首次提交的时候,这两个标记应该是一样的。如果标记不一样,那么该form就会禁止提交,一个错误就会返回给用户。在用户提交一个form时,如果按下浏览器中的后退按钮并尝试重新提交同一个form时,标记就会出现不匹配的现象。
另一方面,如果两个标记值匹配,那么我们就可以确信整个流程是正确的。在这种情况下,Session中的标记值就会被修改为一个新的值,同时允许提交该form。 你也可以使用这个策略来控制对某些页面的直接访问,就好象上面资源保护中描述的一样。例如,假设一个用户将某个应用的页面A收藏到收藏夹中,而页面A只允许通过页面B和C访问。当用户直接通过收藏夹来访问页面A,这时页面的访问顺序就是不正确的,这样同步标记将处在一个不同步的状态,或者它根本就不存在。不论怎样,访问都被禁止了。 e、做一个hidden框,名字自己定,提交后得到这个值放入session,提交前判断session是否为空 解决方案: 1、后台公共类中实现前台的Form中自动生成两个hidden文本功能,一个是作page是否重复提交判断,并由系统自动附上关键值(如struts采用的方案);另一个作为button是否重复提交判断(struts中好像没有)。由后台公共类实现界面两个hidden text自动生成的好处在于公用性。 2、在basic filter中根据两个hidden text值判断是否为重复提交。 3、javascript中作一个公共方法,实现功能:如果需要判断是否重复提交,就给第二个hidden text附上关键值,并使该功能不可用。 . 个人感想:我相信未来该功能一定会被服务器集成,而不再由开发人员进行编码.
----------------------------------------示例代码----------------------------------------------------
第一,对于不支持POST的,可以简单的使用如下代码
if ("POST".equals(request.getMethod())) ...{
// 正常进行
}else...{
// 异常请求
out.print("异常访问");
return;
}
如果是servlet, 可以将doGet方法直接返回,不进行处理就行了
public void doGet(HttpServletRequest request, HttpServletResponse response) ...{
return;
}
public void doPost(HttpServletRequest request, HttpServletResponse response) ...{
// 正常进行操作
}
还可以采用特定的标志来区分,比如
<form><input type="hidden" name="action" value="insert"/></form>
程序里这样判断
if ("POST".equals(request.getMethod()) && ("insert".equals(request.getParameter("action")))) ...{
// 正常进行
}else...{
// 异常请求
out.print("异常访问");
return;
}
第二,判断提交的来源referer,代码如下
if ("POST".equals(request.getMethod())) ...{
String referer = request.getHeader("referer");
if (referer == null || !referer.startsWith("http://"+request.getServerName())) ...{
// 非法来源
return;
}
// 正常进行
}else...{
// 异常请求
out.print("异常访问");
return;
}
第三 防止重复提交的hashCode
在表单显示页面
//生成一个formhash,算法可以自己定,不随便重复就可以了
String formhash = MD5.encode(Long.toString(new Date().getTime()));
//读取当前session里面的hashCode集合,此处使用了Set,方便判断。
Set<String> formhashSession = (Set<String>) session.getAttribute("formhashSession");
if (formhashSession == null) ...{
formhashSession = new HashSet<String>();
}
// 检测重复问题
while (formhashSession.contains(formhash)) ...{
formhash = MD5.encode(Long.toString(new Date().getTime()));
}
// 保存到session里面
formhashSession.add(formhash);
// 保存
session.setAttribute("formhashSession", formhashSession);
表单里面增加如下字段
<input type="hidden" name="formhash" id="formhash" value="<%=formhash%>" />
在表单提交页面进行如下处理
// 拿到表单的formhash
String formhash = upload.getParameter("formhash");
// 拿到session里面的集合
Set<String> formhashSession = (Set<String>) session.getAttribute("formhashSession");
// 如果没有,则是重复提交,或者非法提交
if (formhashSession == null || !formhashSession.contains(formhash)) ...{
out.println("请不要重复提交!");
return;
}
// 下面进行其它的操作
//
// 最后,如果操作成功,从session里面把这个formhash 删掉!
// 以免用户少填写了某个字段,造成表单无法再次提交
formhashSession.remove(formhash);
session.setAttribute("formhashSession", formhashSession);
分享到:
相关推荐
Java表单重复提交是Web开发中常见的问题,可能导致数据不一致和系统异常。要理解这个问题,首先要明白表单提交的基本流程:用户打开表单页面,填写信息,然后点击提交按钮,浏览器向服务器发送请求,服务器处理请求...
### 防止页面的重复提交和刷新 #### 一、引言 在现代Web应用开发过程中,确保数据完整性与用户体验至关重要。其中,“防止页面的重复提交和刷新”这一问题尤为关键,它不仅关系到系统的稳定性,还直接影响用户体验...
2. **Token验证**:当接收到表单提交请求时,先检查Token是否有效。 ```java if (!this.isTokenValid(request) && (int) state > 0) { this.saveToken(request); } else { // 处理业务逻辑 session....
1. **在表单提交前生成令牌**: ```java saveToken(request); ``` 2. **在提交表单的方法中验证令牌**: ```java if(!isTokenValid(request)){ ActionMessages errors = new ActionMessages(); errors.add(...
Java Web 应用系统中,通过表单提交数据是一种非常普遍的操作处理方式。然而,用户无意或有意地刷新页面容易导致数据的重复提交,影响数据的完整性、一致性。本文分析了现有的处理方式的不足,讨论了如何通过基于...
1. **使用统一的方法**:为所有涉及表单提交的Action创建统一的方法来处理令牌的生成和验证。 2. **错误处理**:对于验证失败的情况,应该给出明确的错误提示,告知用户发生了什么问题。 3. **避免使用GET方式提交**...
在Web应用开发中,表单校验是非常重要的环节之一,能够有效防止非法数据的提交,提高系统的安全性与稳定性。Struts2提供了一套完整的表单校验机制,包括但不限于客户端验证、服务器端验证以及自定义验证规则等。 ##...
如果不匹配或者令牌不存在,那么表单提交将被拒绝,以此来防止重复提交或非法请求。 4. **令牌回退**:当表单提交成功后,为了防止用户意外刷新页面导致重复提交,Struts2会清除服务器会话中的令牌。这种行为称为...
在IT行业中,验证码验证功能是网站和应用程序安全的重要组成部分,它可以防止恶意自动化脚本或机器人进行非法操作。本文将深入探讨如何使用Java编程语言来实现验证码验证,主要涉及Servlet、session以及画板对象等...
- 为了防止重复刷新导致验证码改变,可以使用`session`对象存储当前的验证码内容,同时在客户端通过JavaScript获取图片的`src`,并在表单提交时一并发送验证码值。 4. **验证过程** - 客户端输入验证码后,将其值...
系统可能利用jQuery进行表单提交和数据验证,确保信息完整且符合规范。同时,系统通过邮箱验证机制来增加安全性,防止恶意注册或误操作。这里会用到邮件注册的功能,系统向考生提供的邮箱发送一封包含UUID(无重复的...
- 将接收到的二进制数据保存为图片文件,可能需要对文件名进行处理,避免重复或非法字符。 - 记录上传信息,如文件名、上传时间、文件大小等。 - 返回一个JSON或HTML响应,告知前端上传结果,包括成功或失败信息...
1. **网页登录**:有些网站需要登录才能访问,Java爬虫需要模拟登录过程,可能涉及POST提交表单、处理验证码等。 2. **动态加载内容**:现代网页常使用AJAX技术,部分内容动态加载,需使用Selenium、Puppeteer等...
在IT领域,表单验证是Web开发中的一个关键环节,其主要目的是确保用户提交的数据有效、完整且符合预设的规则,从而维护数据的完整性和准确性。"经典表单验证.rar"这个压缩包文件,根据其标题和描述,很可能是包含了...
- POST请求:当需要提交表单数据时,如登录网站,会使用POST请求。 4. **多线程**: - 为了提高爬虫效率,通常会使用多线程并发抓取不同网页,但要注意控制并发量,避免对目标网站造成过大压力。 5. **爬虫策略*...
在本系统中,JSP用于展示注册和登录表单,以及处理表单提交后的结果展示。 4. **MD5加密**:MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,可以将任意长度的数据转化为固定长度的摘要。在用户注册时...
同时,表单提交时会携带用户的验证码输入,以便于Servlet进行验证。 总结,Java验证码制作涉及了字符串生成、图像处理以及服务器与客户端的交互等多个环节。通过学习以上步骤,开发者可以更好地理解验证码的实现...
1. 表单提交:创建一个包含验证码输入框的表单,用户需要输入看到的验证码。 ```html 提交"> ``` 2. 验证码验证:在`SubmitServlet`中,获取用户输入的验证码并与session中的验证码进行比较。 ```java ...
Java汉字验证码是一种用于验证用户身份的安全机制,常用于防止恶意自动化程序(如机器人)进行非法操作,例如注册、登录或提交表单。在本话题中,我们将深入探讨如何使用Java来实现汉字验证码的生成和验证。 1. **...
- 表单提交:用户选择投票选项后,通过POST请求将数据提交到服务器。 7. **安全性考虑**: - 防止SQL注入:使用预编译语句或参数化查询来避免恶意输入影响数据库。 - 用户验证:可能有登录系统以防止重复投票或...