签名机制
平台会对每个接口访问请求的发送者进行身份验证,在请求中需要包含签名信息。
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 "";
    }
}