api平台接口调用,需要通过签名去核对是不是有效的用户,,一般会给两个key,acceeKey
和 secretKey
,第一个相当于用户名,第二个相当于密钥,,,前端通过一定的算法,,将内容和密钥 生成一个签名,,,
后端再根据 内容和密码,生成一个签名,,, 比对这两个签名是否一致,如果一致就是正常用户
这样也不安全,,别人可能会重发你的请求,,盗用你的签名一直刷你的请求,,,
设置一个nonce
:唯一字符串,,请求一次记录一次,保证不重复,,但是只设置一个nonce
服务器压力会很大,,设置一个timestamp
来筛选掉前后五分钟的请求,
package com.cj.apiclient;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.cj.apiclient.model.User;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @author cc
* @date 2025-04-04 21:05
**/
public class ApiClient {
private String baseUrl = "http://localhost:8080";
private String accessKey;
private String secretKey;
public ApiClient(String accessKey, String secretKey) {
this.accessKey = accessKey;
this.secretKey = secretKey;
}
public String getUsernameByGet(User user){
String json = JSONUtil.toJsonStr(user);
HttpResponse httpResponse = HttpRequest.get(baseUrl + "/user/get")
.addHeaders(getHeaderMap(json))
.execute();
String body = httpResponse.body();
return body;
}
private Map<String, String> getHeaderMap(String body) {
Map<String, String> map = new HashMap<>();
map.put("accessKey", accessKey);
map.put("nonce", UUID.randomUUID().toString());
map.put("timestamp", System.currentTimeMillis() + "");
map.put("body",body);
map.put("sign",StringUtils.genSign(body,secretKey));
return map;
}
}
public class StringUtils {
public static String genSign(String body,String secretKey){
Digester md5 = new Digester(DigestAlgorithm.MD5);
String content = body+"."+secretKey;
return md5.digestHex(content);
}
}
@GetMapping("/user/get")
public String getUsernameByGet(User user, HttpServletRequest request){
String accessKey = request.getHeader("accessKey");
String body = request.getHeader("body");
// 判断时间戳是否在前后五分钟之内
String timestamp = request.getHeader("timestamp");
// 判断随机数是否使用过,,可以使用redis的ttl
String nonce = request.getHeader("nonce");
String sign = request.getHeader("sign");
String s = StringUtils.genSign(body, "123");
if (!s.equals(sign)){
throw new RuntimeException("签名错误");
}
return "hehe";
}
springboot自定义starter
自动配置的包,加了之后写配置文件,有自动提示
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
自定义starter,相当于配置了一个带默认属性的bean,,在META-INF
文件夹下面添加spring.factories
文件,将配置类写进去:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.cj.apiclient.ApiClientConfig
遇到的问题,默认属性写在appilication.properites
不生效,,写在application.yml
中生效