如何利用token令牌防止表单重复提交,
第一步:写一个令牌生成器类,
package com.accp.entity;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import sun.misc.BASE64Encoder;
/**
* 功能描述:
* 令牌生成器
* @Author: xiaoke
* @Date:2018/10/18 16:00
* @Description:
*/
public class TokenProcessor {
private TokenProcessor(){}
private static TokenProcessor instance = new TokenProcessor();
public static TokenProcessor getInstance(){
return instance;
}
public String generateTokeCode(){
String value = System.currentTimeMillis()+new Random().nextInt()+"";
// System.getProperty 这个方法可以得到很多系统的属性。
/* String osName = System.getProperty("os.name");
String user = System.getProperty("user.name");
System.out.println("当前操作系统是:" + osName);
System.out.println("当前用户是:" + user);*/
//获取数据指纹,指纹是唯一的
try {
MessageDigest md = MessageDigest.getInstance("md5");
byte[] b = md.digest(value.getBytes());//产生数据的指纹
//Base64编码
BASE64Encoder be = new BASE64Encoder();
be.encode(b);
return be.encode(b);//制定一个编码
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}
第二步在Controller控制器里写个登录方法,在登录成功的时候生成token令牌存储在session会话里:
然后在表单提交的jsp页面中将session存储的token放在表单中用hidden隐藏域装起来,用户就看不见了:
第三步:在控制层写表单提交的方法,这里我用线程休眠了3秒模仿网络卡顿,用户多次点击提交。如果用户提交的表单数据中没有token或者session会话没有token,或者存储在session中的token(令牌)与表单提交的token(令牌)不同,则用户是重复提交了表单
然后我们到页面登录看效果:登录成功后令牌生成了一串字符
控制台输出的token令牌跟页面是一致的
然后我多次点击提交可以看到控制台输出:处理了用户提交一次后,后面网络3秒休眠时间多次提交都是提交不了的,都是输出已经提交 不能重复提交,因为提交成功一次后就清除了session的token令牌
总结:
token令牌就像一个标记,在表单中放一个token,在提交时判断表单token和session保存的token是否不一致或者null空都判断为已经提交过,重复提交