API签名

系统支持两种API的认证方式:Token认证、AK/SK认证。

  • Token认证:用户使用系统生成的授权Token用作认证令牌,服务端根据Token认证请求是否合法,流程简单,但一旦Token泄露,在Token有效期内Token拥有者可以任意调用API,适合对安全性要求不高的场景。

  • AK/SK认证:服务端根据Access Key Id(AK)/ Secret Access Key(SK)加密的方法来验证某个请求的发送者身份。其中AK标识用户,SK作为对称加密通信的秘钥。AK/SK原理使用对称加解密,能够充分校验发送者的身份和保障数据传输的安全性,防止请求被篡改,适合对安全性要求较高的场景。

认证完毕后,若需要使用第三方工具进行可用性测试,可查看API测试;若需要正式调用API,可查看API调用

Token方式

原理

  • 客户端:
    构建附带Token的请求,并发送至服务端。

  • 服务端:
    通过Token进行API调用鉴权

签名使用方式

  • 查看“已提交”API的Token
    适用API创建者对API进行外部测试(测试API可用性),Token查看路径为:API管理-API管理-API-点击API名称-查看API详情

  • 查看“已申请”API的Token
    适用API正式调用情境,Token查看路径为:API管理-我的API-API申请-点击已审批API名称-查看API详情

AK/SK方式

原理

  • 客户端:
        构建请求(包含 Access Key);
        使用请求内容和使用Secret Access Key计算的签名(Signature);
        发送请求(包含Access Key,Signature)到服务端。

  • 服务端:
        根据发送的Access Key查找数据库得到对应的Secret-Key;
        使用同样的算法将请求内容和Secret-Key一起计算签名(Signature)
        对比用户发送的签名和服务端计算的签名,两者相同则认证通过,否则失败。

签名生成方式

系统支持本地生成签名和网站简易生成签名两种方式。

签名的内容

生成API与服务编排

(1)Headers中的参数:
* X-Auth-Key = "APP Key"; //请求的APP Key。请到「我的API-API调用」页面查看APP Key;
* X-Auth-ActionId = "API Id"; //请求API的API Id。每个API拥有唯一的API Id,请到「API管理-API-API详情」中查看API ID;
* X-Auth-Timestamp = "X-Auth-Timestamp"; //时间戳;
(2)Body中的参数:仅Infields中的参数参与签名(不用输入Infields);其他内容(如PageNo,PageSize)均不参与签名。

示例

生成API示例1

在上述示例中,参与签名的内容为:
X-Auth-Key = value1
X-Auth-ActionId = value2
X-Auth-Timestamp = value3
uid = value4

注册API

(1)Headers中的必要参数:X-Auth-Key,X-Auth-ActionId, X-Auth-Timestamp;
(2)API的输入参数:包含位于Query 、Headers、Body位置的输入参数。
注册API示例1

示例

在上述示例中,参与签名的内容为:
X-Auth-Key = value1
X-Auth-ActionId = value2
X-Auth-Timestamp = value3
prod = value4

本地生成签名

具体流程 1.准备参与签名的字段。

2.将签名字段的KeyValuePair按照Key的字典顺序排列(AaBb-Zz,0-9顺序,即大写字母排在小写字母前,数字排在字母后),然后组装成Key1=Value1&Key2=Value2…​&Key n=Value n & APP Secret的字符串(需注意APP Secret放在最后);

3.对生成的字符串进行128位md5算法做信息摘要,并转小写;

4.第3步得到的32位长度的全小写字符串即为生成的签名。

排序示例
* 参与签名的字段:X-Auth-Key = value1;X-Auth-ActionId = value2;X-Auth-Timestamp = value3;prod = value4
* 排序结果:X-Auth-ActionId=value2X-Auth-Key=value1X-Auth-Timestamp=value3prod=value4APP Secret=value5

生成示例
以下是一段 JAVA 代码生成签名的示例,以供用户参考。

public static void main(String[] args) throws Exception {
  Map<String,Object> param = new HashMap<>();
  String sign = getSign("465f90d77a4a4adb86099f3405cc92a7", param);
  System.out.println("md5信息摘要后"+sign);
}
public static String getSign(String appSecret, Map<String,Object> param) throws Exception {
  String formattedString = formatSignatureParam(appSecret, param);
  System.out.println("原始参数md5前:"+formattedString);
  return Hashing.md5().hashBytes(formattedString.getBytes(Charsets.UTF_8)).toString();
}

/**
 *
 * @param sk app secret
 * @param param 参数map,包括header,query和body中的参数
 * @return
 */

private static String formatSignatureParam(String sk, Map<String,Object> param) {
  if (param == null){
    throw new RuntimeException("error param");
  }
  //申请api时的apiId
  param.put("X-Auth-ActionId",5);
  //app key
  param.put("X-Auth-Key",3);
  //当前时间戳,如果时间与服务端时间相差大于10分钟,此次请求将判定为签名错误
  param.put("X-Auth-Timestamp",System.currentTimeMillis());
  System.out.println("时间戳:"+System.currentTimeMillis());
  //使用TreeMap可以自动按照key字典顺序排序
  TreeMap<String, String> paramMap = new TreeMap<>();
  for (Map.Entry<String, Object> en : param.entrySet()) {
  if(null == en.getValue()){
  continue;
  }
//参数应当均为基本类型
  paramMap.put(en.getKey(),en.getValue().toString());
  }
  Set<Map.Entry<String, String>> entries = paramMap.entrySet();
  StringBuilder builder = new StringBuilder();
  for (Map.Entry<String, String> entry : entries) {
    String key = entry.getKey();
    String val = entry.getValue();
    builder.append(key)
        .append("=")
        .append(val)
        .append("&");
  }
  return builder.append(sk).toString();
}


public static String getMD5String(String str) {
  byte[] bytes = null;
  try {
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    bytes = md5.digest(str.getBytes("UTF-8"));
  } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
  } catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
  }
  return bytes2Hex(bytes);
}

private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5',
    '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5',
    '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

public static String bytes2Hex(final byte[] data) {
  return bytes2Hex(data, true);
}

public static String bytes2Hex(final byte[] data, final boolean toLowerCase) {
  return bytes2Hex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}

private static String bytes2Hex(final byte[] data, final char[] toDigits) {
  final int l = data.length;
  final char[] out = new char[l << 1];
  // two characters form the hex value.
  for (int i = 0, j = 0; i < l; i++) {
    out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
    out[j++] = toDigits[0x0F & data[i]];
  }
  return new String(out);
}

网站简易生成签名

具体流程

1.准备参与签名的字段。

APPID
APP KEY
AKSKQUERY

2.打开https://codepen.io/hsunboy/pen/RdYyRb。输入参与签名的参数等内容。

示例

AKSK
  • Body:填写位于Body位置的输入参数,按照json格式填写。若该位置无参数,则不填写。示例中注册API的Body为prod,需写入。

  • Head:填写位于Header位置的输入参数,按照json格式填写。若该位置无参数,则不填写。

  • Query:填写位于Query位置的输入参数,按照json格式填写。若该位置无参数,则不填写。