1. V1接口通用说明
1.1.1. 调用限制
访问 微丰 开放接口(v1),需要遵循以下规则:
- 所有API都是为服务器端调用设计,请不要在客户端(Web前端页面、手机应用等调用),否则可能会存在鉴权泄漏的风险。
- 常规API默认的频次限制为 60次/分钟,所以任何API在1分钟内最多可调用60次。
- 统计分析类API由于涉及计算量较大,仅支持单线程串行调用,禁止并发调用。
1.1.2. 调用格式
HTTP方法
微丰开放接口(v1)可能会使用到以下HTTP方法:
- GET:用于获取数据的接口
- POST:用于创建接口
- PUT:用于修改接口
- DELETE:用于删除接口
我们会在每个接口的文档中注明所使用的 HTTP 方法,调用接口时请以具体的接口文档为准。
调用地址
微丰开放接口的调用地址都符合以下格式之一:
https://[saas子域名].wefeng360.com/api/v1/[接口相对地址]?[URL参数]×tamp=[时间戳]&sign=[签名]
OR
https://[个性化域名+前缀]/api/v1/[接口相对地址]?[URL参数]×tamp=[时间戳]&sign=[签名]
其中被中括号包含部分的含义如下:
变量 | 说明 |
---|---|
saas子域名 | 您访问微丰系统被分配的专属二级域名 |
个性化域名+前缀 | 您访问微丰私有化系统的个性化二级域名和前缀 |
接口相对地址 | 您调用的具体API的相对URL,会在每个API中注明 |
URL参数 | 接口所需的Query String参数 |
时间戳 | 发起请求时的时间戳,格式为Unix Time,即从“1970-01-01 00:00:00”至今的秒数 |
签名 | 身份验证签名,除非明确说明,否则每次API调用都需要携带,计算方法参见下文 [鉴权方法] |
每个接口文档中都会给出类似以下的调用方法: GET /customers 其中包含了 HTTP 方法及接口相对地址,其他部分则需要根据具体情况替换。
参数
接口文档中可能会出现以下三种参数类型:
- URL 中:嵌入在调用地址中的参数,如
/customers/:id
中的:id
; - Query String:调用地址 Query String 部分的参数,如
/customers?page=2
中的page
; - Request Body:请求体中的内容。 当调用创建、修改类接口时,需要将请求数据按照 JSON 格式转换为 UTF-8 文本,将编码后的字符串作为 Request Body 类参数传给对应的接口。 同时将请求头中的 Content-Type 字段设置为 application/json 。
返回结果
- 微丰开放接口(v1)的返回数据同样为JSON格式格式编码的 UTF-8 字符串。
- 微丰开放接口在Response的header中会返回X-Request-Id标识一次唯一请求,如需微丰工程师协助定位接口调用疑问,请务必提供Response中的X-Request-Id。
1.1.3. 鉴权方法
规则说明
所有接口调用需要携带签名参数 sign,只有当 sign 值合法时请求才会被接受。 sign 的计算方法如下:
sign=SHA256(secretKey×tamp)
其中:
- secretKey 为租户秘钥,在微丰系统后台系统对接处获取;
- timestamp 为Unix time,即从“1970-01-01 00:00:00”至今的秒数。
- 注:timestamp有效期为10分钟
示例
假设要调用以下接口:
https://[调用域名]/api/v1/external_contact/:externalUserId
鉴权所需数据如下:
名称 | 数据 |
---|---|
secretKey | 5480583a6494445897pa3s1241 |
timestamp | 1619143576 |
计算sign:
sha256("5480583a6494445897pa3s1241&1619143576")
27aa4b58a5eff9d006c974d62a4b0837e1be1cc90e5a3578aeadbe61d4914220
最终请求URL:
https://[调用域名]/api/v1/external_contact/wm_3b_XXXXXX?sign=fbdd2e45e3bd9d1f1e4915863cff62c2d6f901490070741b821ad55d7e231552×tamp=1619143576
python3示例
from hashlib import sha256
import time
if __name__ == '__main__':
secrekey = "5480583a6494445897pa3s1241"
timestamp = str(int(time.time()))
key = str(secrekey + '&' + timestamp)
sign = sha256(key.encode("utf-8")).hexdigest()
print(sign)
java示例
public class SignUtil {
public static String createSign(String timestamp, String appKey) {
String signStr = appKey + "&" + timestamp;
return createSignWithStr(signStr);
}
public static String createSignWithStr(String signStr) {
String sign = null;
MessageDigest instance;
try {
instance = MessageDigest.getInstance("SHA-256");
instance.update(signStr.getBytes());
sign = byte2Hex(instance.digest());
} catch (Exception e) {
log.error("生成接口签名失败!", e);
}
return sign;
}
/**
* 将byte转为16进制
*
* @param bytes
* @return
*/
private static String byte2Hex(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer();
String temp = null;
for (int i = 0; i < bytes.length; i++) {
temp = Integer.toHexString(bytes[i] & 0xFF);
if (temp.length() == 1) {
//1得到一位的进行补0操作
stringBuffer.append("0");
}
stringBuffer.append(temp);
}
return stringBuffer.toString();
}
}