防止重复请求 get 和post
之前用md5 sha256等加密算法
约束了get请求中防止参数被其他人篡改
但是如果黑客多次请求 该接口  无法被防止
那么需要在get 请求中假如timestamp
get 和 post的区别 get 和post 没有长度限制 长度限制时浏览器决定的 参数位置都一样 get 可以放url中 也可以放body中 post 可以放body中 也可以放url中 只要是http 都不安全 区别是 get 和post get/uri http/1.1 post/uri http/1.1 tcp/ip 协议是可靠的 可以发送大数据 可以发送小数据 但是浏览器仅仅支持地址栏最大发送1024kb 长度限制 但是不是说get 请求有长度限制

 
controll中 最好不要将map 当接受参数 因为参数数量不确定
package com.msb.api; import cn.hutool.core.convert.Convert; import com.msb.api.posttest.SignDTO; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; /** * @author lcc * @version V1.0 * @Package com.msb.api.posttest * @date 2022/5/9 21:12 */ @RestController @RequestMapping("/api-safe") public class ApiSafeController { @RequestMapping("/test") public String test(){ return "test"; } @RequestMapping("/get-test") public String getTest(String appId, String name, String sign, long timeStamp, HttpServletRequest request){ HashMap<String, Object> hashMap = new HashMap<>(); /* 参数写死 hashMap.put("appId",appId); hashMap.put("name",name); hashMap.put("timeStamp",timeStamp);*/ /*下面会把sign 当参数传入 会获取新的sign 肯定会不想同*/ Enumeration<String> parameterNames = request.getParameterNames(); while (parameterNames.hasMoreElements()){ String s = parameterNames.nextElement();//获取请求参数的名字 System.out.print(s+" "); String parameter = request.getParameter(s);//获取请求参数的值 System.out.print(parameter+" "); hashMap.put(s, parameter); } /*让接口在有效期内访问 long time = System.currentTimeMillis() - timeStamp; if(time>1000*30){ return "接口过期了"; //throw TimeException("接口过期了"); }*/ System.out.println("传过来的额sign:"+sign); String s = CheckUtils.generatorSign(hashMap); System.out.println("生成的s"+s); if(s.equals(sign)){//如果前段传过来的sign 签名(经过md5加密过后)后端再来对传输过来的数据进行加密 然后对比看得出来的值是否相等 return "通过"; }else { return "不通过"; } } @PostMapping("/postTest") public String postTest(@RequestBody SignDTO signDTO){ //JSONObject jsonObject = JSONUtil.parseObj(signDTO); // System.out.println(jsonObject); //参数转map Map<String, Object> stringObjectMap = Convert.toMap(String.class, Object.class, signDTO); //排序 Map<String, Object> stringObjectMapSort = CheckUtils.sortMapByKey(stringObjectMap); System.out.println(stringObjectMapSort); //map 生成sign String signServer = CheckUtils.generatorSign(stringObjectMapSort);//因为这里的generatorSign 把sign 移除了 //客户端传来的sign String signClient = (String)stringObjectMap.get("sign"); System.out.println(signClient); //判断签名 if(signServer.equals(signClient)){//如果前段传过来的sign 签名(经过md5加密过后)后端再来对传输过来的数据进行加密 然后对比看得出来的值是否相等 return "通过"; }else { return "不通过"; } } }
package com.msb.api; import com.msb.MD5Util; import java.util.*; import java.util.function.BiFunction; /** * @author lcc * @version V1.0 * @Package com.msb.api * @date 2022/5/9 21:20 */ public class CheckUtils { //appSecret和appId 一一对应 public static String AppSecret="aaa"; //根据map 生成签名 为了排序 public static String generatorSign(Map<String,Object> map){ //先移除sign map.remove("sign"); //排序 Map<String, Object> stringObjectMap = sortMapByKey(map); //转格式 Set<Map.Entry<String, Object>> entries = stringObjectMap.entrySet(); StringBuffer bf = new StringBuffer(); for (Map.Entry<String, Object> entry : entries) { bf.append(entry.getKey()+":"+entry.getValue()+","); } // bf.subSequence(0, bf.length()-1); //组装secret 在参数后面添加 secret bf.append("secret:").append(AppSecret); //生成签名 System.out.println(bf); System.out.println(MD5Util.md5(bf.toString())); return MD5Util.md5(bf.toString());//MD5 算法不可逆 生成的 /*可以将生成的sign 放入redis 中 加入过期时间 如果在时间内 这个人多次访问 只要在redis 中存在这个md5 存在的key * 那么就拒绝访问 * */ } public static Map<String,Object> sortMapByKey(Map<String,Object> map){ TreeMap<String, Object> treeMap = new TreeMap<>(new MyMapComparator()); treeMap.putAll(map); return treeMap; } private static class MyMapComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } } public static void main(String[] args) { HashMap<String, Object> hashMap = new HashMap<>(); /* hashMap.put("ap",1); hashMap.put("zp",2); hashMap.put("cp",3); Map<String, Object> stringObjectMap = sortMapByKey(hashMap); System.out.println(stringObjectMap);*/ hashMap.put("appId",1); hashMap.put("name",2); //hashMap.put("timeStamp", 1650490843064L); // hashMap.put("sign","sddd59fa505b7bd2a352f179d58c2eb90"); String s = generatorSign(hashMap); System.out.println(s);//a3337ee5d708e41ac38bd0d88561b95f } }
package com.msb.api.posttest; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author lcc * @version V1.0 * @Package com.msb.api.posttest * @date 2022/5/10 10:10 */ @AllArgsConstructor @NoArgsConstructor @Data public class SignDTO { private String appId; private String name; private String sign; }
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号