签名机制
平台会对每个接口访问请求的发送者进行身份验证,在请求中需要包含签名信息。
1 签名方法
首先,需要在管理平台 设置/授权管理 页面创建您的appKey
和 appSecret
,其中appKey
用于标识访问者身份;appSecret
是用于加密签名字符串和服务器端验证签名字符串的密钥,须严格保密。如图:
签名参数包括:
参数名 | 参数值 | 参数位置 | 备注 |
---|---|---|---|
x-auth-accesskey | appKey | 请求头 | 为appKey |
x-auth-traceid | 请求唯一ID | 请求头 | 5分钟内不重复 |
x-auth-ts | 13位时间戳 | 请求头 | 请求的时间戳 |
x-auth-body | body | 一般POST、PUT、DELETE等请求时有body,如果不为空,则参与签名 | |
查询字符串 | query/param | 即?key1=value1&key2=value2中的key1,key2 |
超时排错提示
其中x-auth-ts
是调用方当前时间戳,只有当调用方和服务器时间相差较大,才应该查阅接口获取服务器时间戳。
以下是签名方法:
- 按照签名参数名的字典升序排列非空请求参数,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串signText;
- 对signText进行HMAC_MD5运算,
appSecret
作为加密密钥,并将得到的字符串转换为大写,得到x-auth-sign
值,作为请求头的一项值。
2 签名示例
- postman请求签名示例
(function() {
var signContent = [];
var accessKey = pm.environment.get("accessKey");
var secretKey = pm.environment.get("secretKey");
var timestamp = new Date().valueOf();
var traceId = "traceId-" + timestamp;
signContent.push("x-auth-accesskey=" + accessKey);
signContent.push("x-auth-traceid=" + traceId);
signContent.push("x-auth-ts=" + timestamp);
var index = request.url.indexOf("?");
if (index != -1) {
var str = request.url.substr(index + 1);
if (str !== "") {
var params = str.split("&");
signContent = signContent.concat(params);
}
}
if (Object.keys(request.data).length > 0)
signContent.push("x-auth-body=" + request.data);
// 排序后拼接,签名原始字符串
var signText = signContent.sort().join("&");
var sign = CryptoJS.HmacMD5(signText, secretKey)
.toString()
.toUpperCase();
console.log(sign, signText);
pm.environment.set('x-auth-accesskey', accessKey);
pm.environment.set('x-auth-ts', timestamp);
pm.environment.set('x-auth-traceid', traceId);
pm.environment.set('x-auth-sign', sign);
console.log(request);
})();
- Java签名示例
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* seewo iot签名示例
*/
public class SignDemo {
private static final String accessKey = "accessKey";
private static final String secret = "secret";
private static final String HTTP_REQ_BODY = "";
public static void main(String[] args) {
TreeMap<String, String> params = new TreeMap<>();
params.put("x-auth-ts", String.valueOf(System.currentTimeMillis()));
params.put("x-auth-traceid", "traceId-123");
params.put("x-auth-accesskey", accessKey);
if (StringUtils.isNotEmpty(HTTP_REQ_BODY)) {
params.put("x-auth-body", HTTP_REQ_BODY);
}
String sign = createSign(params, secret);
System.err.println(sign);
}
private static String createSign(Map<String, String> params, String accessSecret) {
Set<String> keysSet = params.keySet();
Object[] keys = keysSet.toArray();
Arrays.sort(keys);
StringBuilder temp = new StringBuilder();
boolean first = true;
for (Object key : keys) {
if (first) {
first = false;
} else {
temp.append("&");
}
temp.append(key).append("=");
Object value = params.get(key);
String valueString = "";
if (null != value) {
valueString = String.valueOf(value);
}
temp.append(valueString);
}
return encryptHMAC(temp.toString(), accessSecret)
.toUpperCase(); // 转大写
}
private static String encryptHMAC(@NotNull String data, @NotNull String key) {
try {
SecretKey secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "hmacMD5");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
byte[] digest = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
return new HexBinaryAdapter().marshal(digest);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}