原理:生成token令牌保存在session中,在后台比较前端传来的token于session中token
(其实这是Apache给出的的一种应对方法)
其中有些内容参考至孤傲苍狼大佬的文章:https://www.cnblogs.com/xdp-gacl/p/3859416.html
3种重复提交的情况:
存储Session中的token与表单提交的token不同。
当前用户的Session中不存在token。
用户提交的表单数据中没有token。
生成token的工具类(为了保证对象的唯一性这里用单例模式)
package service;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import org.apache.commons.codec.binary.Base64;
public class TokenUtils {
private TokenUtils() {}
private static final TokenUtils instance = new TokenUtils();
public static TokenUtils getInstance(){
return instance;
}
public String makeToken(){
//生成token用当前的时间毫秒数+一个随机数
String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
try {
//通过MD5进行不可逆加密(其实不加密也没啥关系)
MessageDigest md = MessageDigest.getInstance("md5");
byte md5[] = md.digest(token.getBytes());
//base64编码--任意二进制编码明文字符 adfsdfsdfsf
Base64 encoder = new Base64();
return encoder.encodeAsString(md5);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
token的验证我这里是写在拦截器里的(推荐这样操作,减轻controller的负担)
package interceptor;
import javax.servlet.http.HttpServletRequest;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
public class TokenInterceptor implements Interceptor{
@Override
public void intercept(Invocation inv) {
boolean result=false;
result=isRepeatSubmit(inv.getController().getRequest());
if(result){
System.out.println("请不要重复提交");
}else{
inv.getController().getSession().removeAttribute("token");
inv.invoke();
}
}
(这个是验证的方法,如果你不用jfinal的话就只要这个)
private boolean isRepeatSubmit(HttpServletRequest request) {
String token = request.getParameter("token");
//1、如果用户提交的表单数据中没有token,则用户是重复提交了表单
if(token==null){
return true;
}
//取出存储在Session中的token
String Stoken = (String) request.getSession().getAttribute("token");
//2、如果当前用户的Session中不存在Token(令牌),则用户是重复提交了表单
if(Stoken==null){
return true;
}
//3、存储在Session中的Token(令牌)与表单提交的Token(令牌)不同,则用户是重复提交了表单
if(!token.equals(Stoken)){
return true;
}
return false;
}
}
html页面里加上这个用来后端获取token和session中的token比较
后端记得把token保存到session中