接口调用
浏览服务基本信息¶
用户所申请的接口在通过审核授权后,回到该接口的描述页面,在 参数说明 一栏介绍了该接口的 请求参数 与 返回参数 。此时只显示该接口的公共请求参数,用户可先查看公共请求参数的名称和规则:包括数据类型,是否为必填字段,参数描述。
在 参数说明 的上方,还提供了 调用说明 以及 功能说明 等API的基本服务信息,供用户浏览查看。
其中,接口地址为该API接口的 URL 地址。公共请求参数PAGENUM表示接口调用后返回的连续数据样本数量,参数START代表返回的第一个数据样本的索引。
在线调用接口¶
点击 在线接口调用 按钮,进入在线接口调用页面。在上面的接口参数文本框中输入公共请求参数,点击 接口调用 按钮,用户可在下方的接口参数窗口中得到 JSON格式的返回参数 。如下图:
在该示例的返回内容中,冒号前面的内容为字段,并按照层级进行了缩进。
- 其中“code”为操作码:如响应值为200,则代表成功响应,有具体数据返回;响应值为300代表操作失败,无数据返回。
- "msg"代表操作信息提示。成功响应时,则“msg”返回值为空;若出现错误时,“msg”会返回相应的错误内容。
- “data”中是用户真正所需的返回数据。返回数据的样本量由请求参数PAGENUM决定,用户在这里可以查看部分数据具体值。
用户返回接口的描述界面,在下方 参数说明 中这时就会出现该接口返回参数。该示例接口的请求参数与返回参数详细信息如下图所示:
代码调用接口¶
公共数据开放网站服务调用支持三种方式:
- 基于签名认证的调用 ,需要使用签名认证令牌,且在代码调用接口时要遵循一定的HTTP协议的传输格式,安全性高,推荐开发应用时使用该方式调用接口;
- 基于简单认证的调用 ,安全性低,默认在开放网站的在线接口调用中使用,有调用次数限制,每天调用100次;
- 兼容原开放平台的调用方式 ,在URL中传入
client_id
和client_secret
,此方式只是为了确保基于旧开放网站开发的应用可以正常调用。
基于签名认证的调用¶
用户点击 个人中心 在 我的令牌 选项中可以查看令牌,令牌分为签名认证令牌、简单认证令牌。
网站支持重新生成令牌,以备在令牌泄露后禁用原有令牌,并重新生成新的令牌。
其中签名认证令牌由Client ID
和Client Secret
两部分组成:
Client ID
是令牌的标识,在调用服务时需要传递,用于标识服务调用方。Client Secret
是令牌的密钥,相当于用户密码,需要妥善保存,在调用服务时需要基于此密钥生成签名。
我的令牌 页面如下图所示:
用户要查看Client Secret
需点击后面的 查看 链接,系统会向账号绑定的手机号发送验证码,在下方出现的文本框中输入验证码后,即可查看Client Secret
的具体值。
调用过程
-
返回该接口的描述页面,在 调用说明 一栏中,找到 接口地址 一行中的 URL 地址,并在使用时在URL地址后用' ? '和' & '拼接请求参数名与对应的参数值。用户按格式调用接口的 URL 地址,才能获取相应内容。
-
接口调用最常见的请求方式为 GET 和 POST 两种方式,即读接口和写接口,通过这两种方式,实现对数据的增删查改,其中增删改本质都是写的动作。 GET 请求会将数据放在 URL 地址中, POST 请求会将数据放在消息体Body中。
-
实际的代码调用接口服务必须遵循以下HTTP协议的传输方式的格式:
请求参数名 | 描述 |
---|---|
X-Client-Id | 令牌标识, 前后端约定 |
X-Timestamp | 调用时间戳 |
X-Nonce | 调用方生成的随机数,推荐用UUID |
X-Signature | 调用方生成的签名值 |
-
调用时间戳的值为当前时间的毫秒数,也就是从1970年1月1日起至今的时间转换为毫秒,时间戳有效时间为10分钟。时间戳用于判断请求与当前时间差,超过有效时间请求失效,既防止请求长期有效又允许客户端和服务端之间存在10分钟时间差;
-
随机数有调用方生成,时间戳和随机数组合防止服务重放攻击。
-
调用签名的生成方式为使用
HmacSHA256
算法对 X-Client-Id + X-Timestamp + X-Nonce 组合字符计算后,再经过Base64
编码得到的加密字符串,密钥为签名认证令牌密钥Client Secret
。 -
根据以上要求,在调用请求发送前需对请求参数执行如下的代码片段来实现API网关的签名认证:
import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.UUID;
String serviceUrl = "SERVICE_URL"; // 具体服务的调用地址
int timeout = 500; // 服务调用延时
String clientId = "YOUR_CLIENT_ID"; // 替换为用户的client_id
String timestamp = String.valueOf(Instant.now().toEpochMilli());
String nonce = UUID.randomUUID().toString();
String secret = "YOUR_CLIENT_SECRET"; // 替换为用户的client_secret
String stringToSign = clientId + timestramp + nonce;
String sign = null;
try {
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] keyBytes = secret.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacSHA256"));
sign = Base64.encodeBase64String(hmacSha256.doFinal(stringToSign.getBytes("UTF-8")));
} catch (NoSuchAlgorithmException e) {
} catch (UnsupportedEncodingException e) {
} catch (InvalidKeyException e) {
}
HttpClientBuilder httpClientBuilder = HttpClients.custom().useSystemProperties();
CloseableHttpClient httpClient = httpClientBuilder.build();
HttpPost requestMethod = new HttpPost(); // 根据服务的具体请求方法构造合适的请求方法对象,此处以POST方法为例说明
requestMethod.setURI(serviceUrl);
RequestConfig config = RequestConfig.custom().setConnectTimeout(timeout).build();
requestMethod.setConfig(config);
requestMethod.addHeader("X-Client-Id", clientId);
requestMethod.addHeader("X-Timestamp", timestamp);
requestMethod.addHeader("X-Nonce", nonce);
requestMethod.addHeader("X-Signature", sign);
CloseableHttpResponse response = httpClient.execute(requestMethod);
// 处理返回结果
var url = "<Service URL>";
var clientId = "<Your Client ID>";
var clientSecret = "<Your Client Secret>";
var timestamp = new Date().getTime();
var nonce = createUuid();
var textToSign = appKey + timestamp + nonce;
var hash = CryptoJS.HmacSHA256(textToSign, clientSecret);
var signature = hash.toString(CryptoJS.enc.Base64);
$.ajax({
url: url,
type: "POST",
beforeSend: function(request) {
request.setRequestHeader("X-Client-Id", clientId);
request.setRequestHeader("X-Timestamp", timestamp);
request.setRequestHeader("X-Nonce", nonce);
request.setRequestHeader("X-Signature", signature);
},
success: function(result) {
console.log(result);
}
});
function createUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}
调用说明
以上调用接口的过程信息用户可以在该接口的描述页面中的 调用说明 一栏中查看,如下图:
基于简单认证的调用¶
用户点击 个人中心 后,在 我的令牌 选项中可以查看简单认证令牌, 如下图:
如页面中提示所说,简单认证令牌通过明文传递, 安全性较弱 ,只适合服务在线调用,不建议在开发的应用中使用。用户点击AppKey
的 查看 链接后,即可显示简单认证令牌的具体值。基于简单认证的接口调用的URL地址格式以及调用方式与签名认证调用接口的一致,但在代码调用时不需要实现API网关的签名认证。
import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.UUID;
String serviceUrl = "SERVICE_URL"; // 具体服务的调用地址
int timeout = 500; // 服务调用延时
String appKey = "YOUR APP KEY"; // 替换为用户的AppKey
HttpClientBuilder httpClientBuilder = HttpClients.custom().useSystemProperties();
CloseableHttpClient httpClient = httpClientBuilder.build();
HttpPost requestMethod = new HttpPost(); // 根据服务的具体请求方法构造合适的请求方法对象,此处以POST方法为例说明
requestMethod.setURI(serviceUrl);
RequestConfig config = RequestConfig.custom().setConnectTimeout(timeout).build();
requestMethod.setConfig(config);
requestMethod.addHeader("AppKey", appKey);
CloseableHttpResponse response = httpClient.execute(requestMethod);
// 处理返回结果
兼容原开放平台的调用方式¶
用户点击 个人中心 后,在 我的令牌 选项中可以查看在老平台申请的所有令牌,如果没有则表示不存在这样的令牌。原有的服务调用令牌如下图所示:
如页面中的提示所说,平台在升级后,为确保原来的服务申请可以正常使用,保留了原来的服务调用令牌。平台将逐步禁用该令牌,并替换为最新的服务令牌。