使用 Access Token 调用 API


参考本文使用生成的 Access Token 调用 EnOS API。

开始前准备

  • 调用前需准备参数 appKeyappSecretaccessToken、以及 timestamp

步骤

构造 paramsData

  1. 将所有的已获取的参数名进行 ASCII 码升序排序。
  2. 将排序后的参数名带上参数值进行拼接,具体可参考下文示例。
  3. 如果存在请求 body,则将拼接后字符串再加上请求 body 生成 paramsData

注解

加入签名的请求 body 必须与发送请求的 body 保持一致,否则会导致校验失败。


有关示例参考,参见 请求步骤 中的步骤 1 至 3。

构造 apim-sign

  1. 依次将 accessTokenparamsDatatimestampappSecret 拼接成字符串生成 signData
  2. 使用 SHA256 算法加密 signData 生成预密文。
  3. 将预密文转成小写字母生成 apim-sign,伪代码如下:
sha256(signData).toLowerCase();


有关示例参考,参见 请求步骤 中的步骤 4 和 5。

错误码

代码 描述
0 SUCCESS
1001 重复请求,使用了相同的 encryption
1002 appKey 不存在
1003 encryption 不合法
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

请求步骤

  1. 将 k3、k1、k2 按 ASCII 码升序排列成为 k1、k2、k3。

  2. 依次将 k1v1、k2v2、k3v3 拼接成字符串 k1v1k2v2k3v3。

  3. 依次拼接 k1v1k2v2k3v3 和请求 Body 成为 paramsData

    k1v1k2v2k3v3{
    "count": 20,
    "page": 1,
    "desc": "描述"
    }
    


  4. 依次将 accessTokenparamsDatatimestampappSecret 拼接成如下字符串:

    xxxxaaaxxxxk1v1k2v2k3v3{
    "count": 20,
    "page": 1,
    "desc": "描述"
    }1572574909697xxxappSecretxxx
    


  5. 将第 4 步的字符串使用 SHA256 加密并用小写字母表示,结果为:

    59828328f6c1f9771015dc74e4929ae30f518a35a3d2353972c2ea46556fc981
    


  6. 发送请求:

    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);
    }
}