使用 Access Token 调用 API¶
参考本文使用生成的 Access Token 调用 EnOS API。
开始前准备¶
调用前需准备参数 appKey、appSecret、accessToken、以及 timestamp。
步骤¶
构造 paramsData
¶
将所有的已获取的参数名进行 ASCII 码升序排序。
将排序后的参数名带上参数值进行拼接,具体可参考下文示例。
如果存在请求 body,则将拼接后字符串再加上请求 body 生成
paramsData
。
备注
加入签名的请求 body 必须与发送请求的 body 保持一致,否则会导致校验失败。
有关示例参考,参见 请求步骤 中的步骤 1 至 3。
构造 apim-sign
¶
依次将
accessToken
、paramsData
、timestamp
、appSecret
拼接成字符串生成signData
。使用 SHA256 算法加密
signData
生成预密文。将预密文转成小写字母生成
apim-sign
,伪代码如下:
sha256(signData).toLowerCase();
有关示例参考,参见 请求步骤 中的步骤 4 和 5。
发送请求头的参数 Header¶
将以下内容加入请求 Header:
apim-accesstoken: accessToken
apim-signature: apim-sign
apim-timestamp: timestamp
有关示例参考,参见 请求步骤 中的步骤 6。
错误码¶
代码 |
描述 |
---|---|
0 |
SUCCESS |
1001 |
重复请求,使用了相同的 |
1002 |
|
1003 |
|
1004 |
参数不合法 |
1005 |
内部服务异常 |
1202 |
参数非空 |
1203 |
Access Token 已过期 |
1204 |
刷新 Access Token 失败 |
示例¶
以下示例展示使用 Access Token 调用一个 API 接口的方法。
请求 URL¶
https://{apigw-address}/m/v1/b?k3=v3&k1=v1&k2=v2
请求 Body¶
{
"count": 20,
"page": 1,
"desc": "描述"
}
请求参数¶
参数 |
值 |
---|---|
accessToken |
xxxxaaaxxxx |
appSecret |
xxxappSecretxxx |
timestamp |
1572574909697 |
请求步骤 ¶
将 k3、k1、k2 按 ASCII 码升序排列成为 k1、k2、k3。
依次将 k1v1、k2v2、k3v3 拼接成字符串 k1v1k2v2k3v3。
依次拼接
k1v1k2v2k3v3
和请求 Body 成为paramsData
。k1v1k2v2k3v3{ "count": 20, "page": 1, "desc": "描述" }
依次将
accessToken
、paramsData
、timestamp
、appSecret
拼接成如下字符串:xxxxaaaxxxxk1v1k2v2k3v3{ "count": 20, "page": 1, "desc": "描述" }1572574909697xxxappSecretxxx
将第 4 步的字符串使用 SHA256 加密并用小写字母表示,结果为:
59828328f6c1f9771015dc74e4929ae30f518a35a3d2353972c2ea46556fc981
发送请求:
curl https://{apigw-address}/m/v1/b?k3=v3&k1=v1&k2=v2 -X POST -H 'apim-accesstoken:xxxxaaaxxxx' -H 'apim-signature:59828328f6c1f9771015dc74e4929ae30f518a35a3d2353972c2ea46556fc981' -H 'apim-timestamp:1572574909697' -d '{ "count": 20, "page": 1, "desc": "描述" }'
Java 调用示例¶
import okhttp3.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class EncryptUtils {
/**
* 利用Java原生的类实现SHA256加密
*
* @param str 加密后的参数
* @return
*/
public static String getSHA256(String str) {
MessageDigest messageDigest;
String encodestr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(str.getBytes(StandardCharsets.UTF_8));
encodestr = hexString(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
return encodestr;
}
return encodestr;
}
private static String hexString(byte[] b) {
StringBuilder hs = new StringBuilder();
String stmp;
for (int n = 0; b != null && n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1) {
hs.append('0');
}
hs.append(stmp);
}
return hs.toString();
}
public static void main(String[] args) throws IOException {
String accssToken = "xxxxaaaxxxx";
String appSecret = "xxxappSecretxxx";
long timestamp = 1572574909697L;//System.currentTimeMillis();
String url = "https://{apigw-address}/m/v1/b?k3=v3&k1=v1&k2=v2";
String requestBody = "{\n" +
" \"count\": 20,\n" +
" \"page\": 1,\n" +
" \"desc\": \"描述\"\n" +
"}";
HttpUrl httpUrl = HttpUrl.parse(url);
if (httpUrl == null) {
return;
}
List<String> keys = new ArrayList<>(httpUrl.queryParameterNames());
Collections.sort(keys);
StringBuilder paramsData = new StringBuilder();
for (String key : keys) {
String value = httpUrl.queryParameter(key);
paramsData.append(key).append(value);
}
paramsData.append(requestBody);
String signData = accssToken + paramsData.toString() + timestamp + appSecret;
String apimSign = getSHA256(signData);
RequestBody body = FormBody
.create(MediaType.parse("application/json; charset=utf-8"), requestBody);
Request request = new Request.Builder().url(url).method("POST", body)
.addHeader("apim-accesstoken", accssToken)
.addHeader("apim-signature", apimSign)
.addHeader("apim-timestamp", timestamp + "")
.build();
String res = new OkHttpClient().newCall(request).execute().body().string();
System.out.println(res);
}
}