# Sign方式v4(非对称加密)
需要申请对应环境的appKey与appSecret
测试域名:https://openapi-test.babycare.com/api/gateway
正式域名:https://gateway.babycare.com
# 1、请求的公共参数(Header)
| 名称 | 类型 | 必填 | 描述 |
|---|---|---|---|
| appKey | String | 是 | 请求应用编码 |
| signRequestId | String | 是 | 请求号(一个随机编码),参与签名 |
| signRequestTime | String | 是 | 请求时间戳(单位:秒),参与签名 |
| signVersion | String | 是 | 4.0 , 参与签名 |
| sign | String | 是 | 签名 |
签名参数是放在header头部中的,不能在url参数拼接或者放在body体中
# 2、签名算法
# 签名⽣成的通⽤步骤如下:
# 第一步:
将所有⾮空请求参数(包括Header中参与签名参数,Body参数,QueryString参数),按照参数名ASCII码从⼩到⼤排序(字典序),使 ⽤URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
# 注意事项:
1、参数名ASCII码从⼩到⼤排序(字典顺序)
2、如果参数的值为空不参与签名;
3、参数名区分⼤⼩写;
# 第⼆步:
在stringA最后拼接上
key=appSecret得到stringSignTemp字符串,并对stringSignTemp进⾏MD5运算,再将得到的字符串所有字符转 换为⼤写,得到sign值signValue。
# Java代码示例
public static void main(String[] args) {
//访问appKey
String appKey = "需要申请";
//访问appSecret
String appSecret = "需要申请";
//版本号
String signVersion = "4.0";
//网关地址
String gatewayUrl = "网关地址";
// 构造参数使用treeMap保证构建sign字符串时有序
Map<String, Object> params = Maps.newTreeMap();
// 基础参数 用户加密
String signRequestId = UUID.randomUUID().toString();
long signRequestTime = System.currentTimeMillis() / 1000;
//加密参数
params.put("signVersion", signVersion);
params.put("signRequestId", signRequestId);
params.put("signRequestTime", signRequestTime);
//不管是body中的参数,还是url拼接的参数都要参与签名
//要放到boody的参数
Map<String,Object> bodyParam = Maps.newHashMap();
bodyParam.put("name","zhangsan");
bodyParam.put("age",12);
params.putAll(bodyParam);
//要放到url做拼接的参数
Map<String,Object> urlParam = Maps.newHashMap();
urlParam.put("id",12);
params.putAll(urlParam);
String sign = sign(appSecret, params);
HttpHeaders headers = setHeaders(appKey, signVersion, signRequestId, signRequestTime, sign);
RestTemplate restTemplate = new RestTemplate();
HttpEntity<JSONObject> request = new HttpEntity<JSONObject>(JSONObject.toJSONString(bodyParam), headers);
// /test03/aaa/bbb 为应用接口访问地址(包含路由)
// 案例是post请求,get请求修改类型,并传参数用url拼接的方式
ResponseEntity<Object> entity = restTemplate.exchange
(gatewayUrl + "/test03/aaa/bbb?id=12", HttpMethod.POST, request, Object.class);
System.out.println(entity.getBody());
}
/**
* 加密
* @param appSecret
* @param params
* @return
*/
private static String sign(String appSecret, Map<String, Object> params) {
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, Object> entry : params.entrySet()) {
if (Objects.isNull(entry.getValue())) {
continue;
}
builder.append(entry.getKey())
.append("=")
.append(entry.getValue())
.append("&");
}
// 将key拼接到字符串末尾
builder.append("key=").append(appSecret);
// sign进行加密
return DigestUtils.md5Hex(builder.toString()).toUpperCase();
}
/**
* 设置头部参数
*
* @param appKey
* @param signApiVersion
* @param signRequestId
* @param signRequestTime
* @param sign
* @return
*/
private static HttpHeaders setHeaders(String appKey, String signVersion, String signRequestId, long signRequestTime, String sign) {
HttpHeaders headers = new HttpHeaders();
headers.set("appKey", appKey);
headers.set("sign", sign);
headers.set("signVersion", signVersion);
headers.set("signRequestId", signRequestId);
headers.set("signRequestTime", signRequestTime + "");
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}