1.API接口鉴权方式介绍
为保证API调用过程的安全可靠,e签宝开放平台OpenApi接口统一采用HTTPS传输协议,并提供以下两种接口鉴权方式,开发者可根据自身情况任选一种方式。
请求签名鉴权方式请求头(优先推荐)
采用请求数据签名方式进行接口鉴权,防止请求数据被篡改,详见文中下方 2.请求签名鉴权方式使用说明。
OAuth2.0鉴权接口调用方式(不推荐使用)
采用标准 OAuth2.0 Client Credentials 方式进行接口鉴权,详见文中下方 3.OAuth2.0鉴权方式使用说明。
2.请求签名鉴权方式使用说明(优先推荐)
第三方应用申请采用请求签名鉴权方式之前,需要先登录e签宝开放平台创建应用,应用创建成功后可以获取到身份识别信息:应用 ID(APP ID)和应用密钥(APP KEY)。
接口调用鉴权方式选择请求签名鉴权方式时,每次调用接口时无需在Header请求头中携带“X-Tsign-Open-Token”,传入授权码Token。
而是需要在调用API前,需要拼接签名字符串,并将签名计算后的字符串放在请求的 Header 传入,e签宝网关会通过Request请求中Header请求头中的X-Tsign-Open-Ca-Signature参数来获取签名值,然后通过计算签名来验证请求者的身份。
2.1 请求签名鉴权方式-请求头
当接口调用选择请求签名鉴权方式,其请求头格式如下:
参数名称 | 类型 | 必选 | 参数说明 |
X-Tsign-Open-Auth-Mode | string | 是 | 接口鉴权方式,请填写固定值:Signature |
X-Tsign-Open-App-Id | string | 是 | 应用ID |
X-Tsign-Open-Ca-Signature | string | 是 | 请求签名值 |
X-Tsign-Open-Ca-Timestamp | string | 是 | 接口调用时的Unix时间戳,单位毫秒。 防重防攻击,时间戳有效期为15分钟。 |
Content-MD5 | string | 否 | 当请求Body体为非Form格式时,需要对Body体计算ContentMD5并传给网关进行校验。 application/json格式的Body体时此项必选。 |
Content-Type | string | 是 | application/json;charset=UTF-8 |
Accept | string | 是 | 建议统一填写 */* |
PostMan中示例如下:

2.2 计算请求签名值
步骤一:待签字符串准备
待签字符串由以下字段拼接组成:
参数 | 说明 |
HTTPMethod | 全大写,例如:POST |
Accept | 希望服务器响应发送回来的是json格式的内容,例如:*/* 或 application/json。 |
Content-MD5 | 当请求Body体为非Form格式时,需要对Body体计算ContentMD5。application/json格式的Body体时此项必选。 |
Content-Type | 请求的与实体对应的MIME信息,例如:application/json;charset=UTF-8 |
Date | 可选,Date头域表示消息发送的时间,缓存在评估响应的新鲜度时要用到,时间的描述格式由RFC822定义。例如,Date: Thu, 11 Jul 2015 15:33:24 GMT。 |
Headers | 可选,对请求的自定义Header进行签名,生成方法见下方 |
Url | url ,对请求的url进行签名(域名无需参与签名), 例如:/v2/identity/auth/web/indivAuthUrl,生成方法见下方 |
(1)待签字符串的拼接方法
String stringToSign=
HTTPMethod + "\n" +
Accept + "\n" +
Content-MD5 + "\n"
Content-Type + "\n" +
Date + "\n" +
Headers +
Url
其中HTTPMethod为全大写,Accept、Content-MD5、Content-Type、Date 如果为空也需要添加换行符”\n”,Headers如果为空不需要添加“\n”。
注:当请求body为空时,必须设置 Content-MD5="",
否则接口鉴权会报错:"code":401,"message":"INVALID_SIGNATURE"。
(2)Content-MD5的计算方法
Content-MD5 是指 Body 的 MD5 值,只有当 Body 格式为非 Form 表单时才计算 MD5。
计算方式为:
1. 首先对某文件或字符串计算出MD5二进制数组,即128位的MD5 Byte[],而不是32位的MD5字符串。
2. 然后对MD5二进制数组进行Base64编码。
点击查看ContentMD5计算方法及示例。
(3)Headers的添加方法
Headers 是指参与 Headers 签名计算的 Header 的 Key、Value 拼接的字符串,建议对 X-Tsign 开头以及自定义 Header 计算签名。若无需对Headers进行签名,可以设为空。
先对参与 Headers 签名计算的 Header的Key 按照字典排序后使用如下方式拼接,如果某个 Header 的 Value 为空,则使用 HeaderKey + “:” + “\n”参与签名,需要保留 Key 和英文冒号。
String headers =
HeaderKey1 + ":" + HeaderValue1 + "\n"\+
HeaderKey2 + ":" + HeaderValue2 + "\n"\+
...
HeaderKeyN + ":" + HeaderValueN + "\n"
若添加了Headers,则需要将 Headers 签名中 Header 的 Key 使用英文逗号分割放到 Request 的 Header 中,Key为:X-Tsign-open-Ca-Signature-Headers。
(4)Url的添加方法
Url 指 Path + Query + Body 中 Form 参数,组织方法:对 Query+Form 参数按照字典对 Key 进行排序后按照如下方法拼接,如果 Query 或 Form 参数为空,则 Url = Path,不需要添加 ?,如果某个参数的 Value 为空只保留 Key 参与签名,等号不需要再加入签名。
String url =
Path +
"?" +
Key1 + "=" + Value1 +
"&" + Key2 + "=" + Value2 +
...
"&" + KeyN + "=" + ValueN
注意:
- Query或Form参数的 Value 可能有多个,多个的时候只取第一个 Value 参与签名计算。
- Query参数的Value如果存在中文,则需要对Value值进行UrlEncode编码,否则会出现中文乱码或签名报错等情况。
步骤二:计算请求签名值
使用应用密钥(APP KEY)对待签名字符串采用HmacSHA256算法进行签名运算,从而得到签名字符串。
查看《2.4请求签名值计算示例代码》
2.3 调用具体API接口
按照具体API接口文档中的描述进行接口调用,调用时参考 2.1 请求签名鉴权方式-请求头 描述传递请求头。
2.4 请求签名鉴权示例代码(Java)
请求签名值计算示例代码
/***
* 计算请求签名值
*
* @param message 待签名字符串
* @param secret 密钥APP KEY
* @return HmacSHA256计算后摘要值的Base64编码
* @throws Exception 加密过程中的异常信息
*/
public String doSignatureBase64(String message, String secret) throws Exception {
String algorithm = "HmacSHA256";
Mac hmacSha256;
String digestBase64 = null;
try {
hmacSha256 = Mac.getInstance(algorithm);
byte[] keyBytes = secret.getBytes("UTF-8");
byte[] messageBytes = message.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm));
// 使用HmacSHA256对二进制数据消息Bytes计算摘要
byte[] digestBytes = hmacSha256.doFinal(messageBytes);
// 把摘要后的结果digestBytes使用Base64进行编码
digestBase64 = new String(Base64.encodeBase64(digestBytes), "UTF-8");
} catch (NoSuchAlgorithmException e) {
String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
} catch (UnsupportedEncodingException e) {
String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
} catch (InvalidKeyException e) {
String msg = MessageFormat.format("无效的密钥规范: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
}
return digestBase64;
}
请求签名鉴权完整示例代码
Test类
package esign.gateway.demo;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.LinkedHashMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import net.sf.json.JSONObject;
public class Test {
public static void main(String[] args) {
// 应用ID
String appId = "4438XX6";
// 应用密钥
String appKey = "73935c284XX0c691f03";
// 接口调用域名
String host = "https://smlopenapi.esign.cn";
// 个人账户ID
String accountId = "4c66c987eXXXc2eb474b5abc54";
// 请求签名鉴权-POST请求
testPost(appId, appKey, host);
// 请求签名鉴权-GET请求
testGet(appId, appKey, host, accountId);
}
/***
* 请求签名鉴权-POST请求
*
* @param appId
* @param appKey
* @param host
*/
public static void testPost(String appId, String appKey, String host) {
// 个人创建账号接口地址
String accountsApi = "/v1/accounts/createByThirdPartyUserId";
// 个人创建账号接口请求地址
String accountsApiUrl = host + accountsApi;
try {
// 构建请求Body体
JSONObject reqBodyObj = new JSONObject();
reqBodyObj.put("thirdPartyUserId", "229");
reqBodyObj.put("name", "张三");
reqBodyObj.put("idType", "CRED_PSN_CH_IDCARD");
reqBodyObj.put("idNumber", "330621");
reqBodyObj.put("mobile", "152****4800");
reqBodyObj.put("email", "152****800@163.com");
// 请求Body体数据
String reqBodyData = reqBodyObj.toString();
// 对请求Body体内的数据计算ContentMD5
String contentMD5 = doContentMD5(reqBodyData);
// 构建待签名字符串
String method = "POST";
String accept = "*/*";
String contentType = "application/json; charset=UTF-8";
String url = accountsApi;
String date = "";
String headers = "";
StringBuffer sb = new StringBuffer();
sb.append(method).append("\n").append(accept).append("\n").append(contentMD5).append("\n")
.append(contentType).append("\n").append(date).append("\n");
if ("".equals(headers)) {
sb.append(headers).append(url);
} else {
sb.append(headers).append("\n").append(url);
}
// 构建参与请求签名计算的明文
String plaintext = sb.toString();
// 计算请求签名值
String reqSignature = doSignatureBase64(plaintext, appKey);
// 获取时间戳(精确到毫秒)
long timeStamp = timeStamp();
// 构建请求头
LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
header.put("X-Tsign-Open-App-Id", appId);
header.put("X-Tsign-Open-Auth-Mode", "Signature");
header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
header.put("Accept", accept);
header.put("Content-Type", contentType);
header.put("X-Tsign-Open-Ca-Signature", reqSignature);
header.put("Content-MD5", contentMD5);
// 发送POST请求
String result = HTTPHelper.sendPOST(accountsApiUrl, reqBodyData, header, "UTF-8");
JSONObject resultObj = JSONObject.fromObject(result);
System.out.println("请求返回信息: " + resultObj.toString());
} catch (Exception e) {
e.printStackTrace();
String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
System.out.println(msg);
}
}
/***
* 请求签名鉴权-GET请求
*
* @param appId
* @param appKey
* @param host
* @param flowId
*/
public static void testGet(String appId, String appKey, String host, String flowId) {
// 签署流程查询API地址
String getSignFlowApi = "/v1/signflows/" + flowId;
// 签署流程查询接口请求地址
String hostGetSignFlowApi = host + getSignFlowApi;
try {
// GET请求时ContentMD5为""
String contentMD5 = "";
// 构建待签名字符串
String method = "GET";
String accept = "*/*";
String contentType = "application/json;charset=UTF-8";
String url = getSignFlowApi;
String date = "";
String headers = "";
StringBuffer sb = new StringBuffer();
sb.append(method).append("\n").append(accept).append("\n").append(contentMD5).append("\n")
.append(contentType).append("\n").append(date).append("\n");
if ("".equals(headers)) {
sb.append(headers).append(url);
} else {
sb.append(headers).append("\n").append(url);
}
// 构建参与请求签名计算的明文
String plaintext = sb.toString();
// 计算请求签名值
String reqSignature = doSignatureBase64(plaintext, appKey);
// 获取时间戳(精确到毫秒)
long timeStamp = timeStamp();
// 构建请求头
LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
header.put("X-Tsign-Open-App-Id", appId);
header.put("X-Tsign-Open-Auth-Mode", "Signature");
header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
header.put("Accept", accept);
header.put("Content-Type", contentType);
header.put("X-Tsign-Open-Ca-Signature", reqSignature);
header.put("Content-MD5", contentMD5);
// 发送GET请求
String result = HTTPHelper.sendGet(hostGetSignFlowApi, header, "UTF-8");
JSONObject resultObj = JSONObject.fromObject(result);
System.out.println("请求返回信息: " + resultObj.toString());
} catch (Exception e) {
e.printStackTrace();
String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
System.out.println(msg);
}
}
/***
*
* @param str 待计算的消息
* @return MD5计算后摘要值的Base64编码(ContentMD5)
* @throws Exception 加密过程中的异常信息
*/
public static String doContentMD5(String str) throws Exception {
byte[] md5Bytes = null;
MessageDigest md5 = null;
String contentMD5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
// 计算md5函数
md5.update(str.getBytes("UTF-8"));
// 获取文件MD5的二进制数组(128位)
md5Bytes = md5.digest();
// 把MD5摘要后的二进制数组md5Bytes使用Base64进行编码(而不是对32位的16进制字符串进行编码)
contentMD5 = new String(Base64.encodeBase64(md5Bytes), "UTF-8");
} catch (NoSuchAlgorithmException e) {
String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
} catch (UnsupportedEncodingException e) {
String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
}
return contentMD5;
}
/***
* 计算请求签名值
*
* @param message 待计算的消息
* @param secret 密钥
* @return HmacSHA256计算后摘要值的Base64编码
* @throws Exception 加密过程中的异常信息
*/
public static String doSignatureBase64(String message, String secret) throws Exception {
String algorithm = "HmacSHA256";
Mac hmacSha256;
String digestBase64 = null;
try {
hmacSha256 = Mac.getInstance(algorithm);
byte[] keyBytes = secret.getBytes("UTF-8");
byte[] messageBytes = message.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm));
// 使用HmacSHA256对二进制数据消息Bytes计算摘要
byte[] digestBytes = hmacSha256.doFinal(messageBytes);
// 把摘要后的结果digestBytes转换成十六进制的字符串
// String digestBase64 = Hex.encodeHexString(digestBytes);
// 把摘要后的结果digestBytes使用Base64进行编码
digestBase64 = new String(Base64.encodeBase64(digestBytes), "UTF-8");
} catch (NoSuchAlgorithmException e) {
String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
} catch (UnsupportedEncodingException e) {
String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
} catch (InvalidKeyException e) {
String msg = MessageFormat.format("无效的密钥规范: {0}", e.getMessage());
Exception ex = new Exception(msg);
ex.initCause(e);
throw ex;
}
return digestBase64;
}
/***
* 获取时间戳(毫秒级)
*
* @return 毫秒级时间戳,如 1578446909000
*/
public static long timeStamp() {
long timeStamp = System.currentTimeMillis();
return timeStamp;
}
}
HTTPHelper辅助类
package esign.gateway.demo;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HTTPHelper {
// slf4j日志记录器
private static final Logger LOG = LoggerFactory.getLogger(HTTPHelper.class);
/***
* 向指定URL发送GET方法的请求
*
* @param apiUrl
* @param data
* @param projectId
* @param signature
* @param encoding
* @return
* @throws Exception
*/
public static String sendGet(String apiUrl, LinkedHashMap<String, String> headers,
String encoding) throws Exception {
// 获得响应内容
String http_RespContent = null;
HttpURLConnection httpURLConnection = null;
int http_StatusCode = 0;
String http_RespMessage = null;
try {
LOG.info(">>>> 实际请求Url: " + apiUrl);
// 建立连接
URL url = new URL(apiUrl);
httpURLConnection = (HttpURLConnection) url.openConnection();
// 需要输出
httpURLConnection.setDoOutput(true);
// 需要输入
httpURLConnection.setDoInput(true);
// 不允许缓存
httpURLConnection.setUseCaches(false);
// HTTP请求方式
httpURLConnection.setRequestMethod("GET");
// 设置Headers
if (null != headers) {
for (String key : headers.keySet()) {
httpURLConnection.setRequestProperty(key, headers.get(key));
}
}
// 连接会话
httpURLConnection.connect();
// 获得响应状态(HTTP状态码)
http_StatusCode = httpURLConnection.getResponseCode();
// 获得响应消息(HTTP状态码描述)
http_RespMessage = httpURLConnection.getResponseMessage();
// 获得响应内容
if (HttpURLConnection.HTTP_OK == http_StatusCode) {
// 返回响应结果
http_RespContent = getResponseContent(httpURLConnection);
} else {
// 返回非200状态时响应结果
http_RespContent = getErrorResponseContent(httpURLConnection);
String msg =
MessageFormat.format("请求失败: Http状态码 = {0} , {1}", http_StatusCode, http_RespMessage);
LOG.info(msg);
}
} catch (UnknownHostException e) {
String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
Exception ex = new Exception(message);
ex.initCause(e);
throw ex;
} catch (MalformedURLException e) {
String message = MessageFormat.format("格式错误的URL: {0}", e.getMessage());
Exception ex = new Exception(message);
ex.initCause(e);
throw ex;
} catch (IOException e) {
String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
Exception ex = new Exception(message);
ex.initCause(e);
throw ex;
} catch (Exception e) {
String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
Exception ex = new Exception(message);
ex.initCause(e);
throw ex;
} finally {
if (null != httpURLConnection) {
httpURLConnection.disconnect();
}
}
return http_RespContent;
}
/***
* 向指定URL发送POST方法的请求
*
* @param apiUrl
* @param data
* @param projectId
* @param signature
* @param encoding
* @return
* @throws Exception
*/
public static String sendPOST(String apiUrl, String data, LinkedHashMap<String, String> headers,
String encoding) throws Exception {
// 获得响应内容
String http_RespContent = null;
HttpURLConnection httpURLConnection = null;
int http_StatusCode = 0;
String http_RespMessage = null;
try {
// 建立连接
URL url = new URL(apiUrl);
httpURLConnection = (HttpURLConnection) url.openConnection();
// 需要输出
httpURLConnection.setDoOutput(true);
// 需要输入
httpURLConnection.setDoInput(true);
// 不允许缓存
httpURLConnection.setUseCaches(false);
// HTTP请求方式
httpURLConnection.setRequestMethod("POST");
// 设置Headers
if (null != headers) {
for (String key : headers.keySet()) {
httpURLConnection.setRequestProperty(key, headers.get(key));
}
}
// 连接会话
httpURLConnection.connect();
// 建立输入流,向指向的URL传入参数
DataOutputStream dos = new DataOutputStream(httpURLConnection.getOutputStream());
// 设置请求参数
dos.write(data.getBytes(encoding));
dos.flush();
dos.close();
// 获得响应状态(HTTP状态码)
http_StatusCode = httpURLConnection.getResponseCode();
// 获得响应消息(HTTP状态码描述)
http_RespMessage = httpURLConnection.getResponseMessage();
// 获得响应内容
if (HttpURLConnection.HTTP_OK == http_StatusCode) {
// 返回响应结果
http_RespContent = getResponseContent(httpURLConnection);
} else {
// 返回非200状态时响应结果
http_RespContent = getErrorResponseContent(httpURLConnection);
String msg =
MessageFormat.format("请求失败: Http状态码 = {0} , {1}", http_StatusCode, http_RespMessage);
LOG.info(msg);
}
} catch (UnknownHostException e) {
String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
Exception ex = new Exception(message);
ex.initCause(e);
throw ex;
} catch (MalformedURLException e) {
String message = MessageFormat.format("格式错误的URL: {0}", e.getMessage());
Exception ex = new Exception(message);
ex.initCause(e);
throw ex;
} catch (IOException e) {
String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
Exception ex = new Exception(message);
ex.initCause(e);
throw ex;
} catch (Exception e) {
String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
Exception ex = new Exception(message);
ex.initCause(e);
throw ex;
} finally {
if (null != httpURLConnection) {
httpURLConnection.disconnect();
}
}
return http_RespContent;
}
/***
* 读取HttpResponse响应内容
*
* @param httpURLConnection
* @return
* @throws UnsupportedEncodingException
* @throws IOException
*/
private static String getResponseContent(HttpURLConnection httpURLConnection)
throws UnsupportedEncodingException, IOException {
StringBuffer contentBuffer = null;
BufferedReader responseReader = null;
try {
contentBuffer = new StringBuffer();
String readLine = null;
responseReader =
new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
while ((readLine = responseReader.readLine()) != null) {
contentBuffer.append(readLine);
}
} finally {
if (null != responseReader) {
responseReader.close();
}
}
return contentBuffer.toString();
}
/***
* 读取HttpResponse响应内容
*
* @param httpURLConnection
* @return
* @throws UnsupportedEncodingException
* @throws IOException
*/
private static String getErrorResponseContent(HttpURLConnection httpURLConnection)
throws UnsupportedEncodingException, IOException {
StringBuffer contentBuffer = null;
BufferedReader responseReader = null;
try {
contentBuffer = new StringBuffer();
String readLine = null;
responseReader =
new BufferedReader(new InputStreamReader(httpURLConnection.getErrorStream(), "UTF-8"));
while ((readLine = responseReader.readLine()) != null) {
contentBuffer.append(readLine);
}
} finally {
if (null != responseReader) {
responseReader.close();
}
}
return contentBuffer.toString();
}
}
3.OAuth2.0鉴权方式使用说明(不推荐)
OAuth 2.0 是目前比较流行的授权机制,用来授权第三方应用,获取接口调用权限。
e签宝服务端产生一个短期的接口调用令牌(Token),后续在令牌(Token)有效期内第三方应用可以通过Token获取接口调用权限。
e签宝将令牌(Token)统一描述为鉴权Token/授权码Token。
第三方应用申请授权码Token之前,需要先登录e签宝开放平台创建应用,应用创建成功后可以获取到身份识别信息:应用ID(APP ID)和应用密钥(APP KEY)。
接口鉴权选择OAuth2.0鉴权方式时,每次调用接口时需要在Header请求头中携带“X-Tsign-Open-Token”,传入授权码Token。
3.1 OAuth2.0鉴权方式-请求头
当接口调用选择OAuth2.0鉴权方式,其请求头格式如下:
参数名称 | 类型 | 必选 | 参数说明 |
X-Tsign-Open-App-Id | string | 是 | 应用ID |
X-Tsign-Open-Token | string | 是 | 授权码Token |
Content-Type | string | 是 | application/json;charset=UTF-8 |
PostMan中示例如下:

3.2 获取鉴权Token
接口描述
通过应用ID和应用密钥获取授权码Token,用来请求api接口。授权码Token有效时长为120分钟。
当授权码Token即将到期时需要调用接口重新获取授权码Token。旧授权码Token可以与新授权码Token共存5分钟,5分钟后旧授权码Token失效。
e签宝服务端允许开发者多次调用“获取鉴权Token”接口获取授权码Token。但只有最新获取的授权码Token的有效时长为120分钟。
举例:
连续获取100个授权码Token(T1,T2,……,T99,T100),此时T1-T98个Token属于失效Token无权调用接口。而T99个Token有效时长为5分钟,T100个Token有效时长为120分钟。
如果开发者同时有多台服务器调用api接口,建议使用集中存储方式保存授权码Token以确保授权码Token值的唯一。
接口地址
/v1/oauth2/access_token
请求方式
GET
请求参数
参数名称 | 类型 | 必选 | 参数类型 | 参数说明 | |
appId | string | 是 | query | 应用id,需在e签宝开放平台创建 | |
secret | string | 是 | query | 应用密钥,不可泄露 | |
grantType | string | 是 | query | 授权类型,固定值: client_credentials |
响应参数
展开全部参数参数名称 | 类型 | 必选 | 参数说明 | |
code | int | 是 | 业务码,0表示成功 | |
message | string | 否 | 信息 | |
data | object | 否 | 业务信息 | |
token | string | 否 | 授权码 注意:120分钟失效,请在expiresIn参数的有效截止时间失效前重新获取token,建议提前5分钟重新获取。 | |
expiresIn | string | 否 | 有效截止时间(毫秒) | |
refreshToken | string | 否 | 刷新授权码 |
请求示例
{接口请求域名}/v1/oauth2/access_token?appId=111156XX41&secret=753b9XXXXXXXXXX3e3374c1&grantType=client_credentials
POSTMAN示例

响应参数
{
"code":0,
"message":"成功",
"data":{
"expiresIn":"1569211376807",
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJnSWQiOiI4N2I4YmJhNGY2N2U0ZjRiODQ3Njc2M2FmNTRjZGYxYSIsImFwcElkIjoiNDQzODc3MTgwOSIsIm9JZCI6ImJiZDNlYTExZWY0ZDQyNmI4NTYzNDhmYjg1MDYxM2ZmIiwidGltZXN0YW1wIjoxNTY5MjA0MTc2ODA2fQ.tiXdZeKPNWFrbt-i3fJfe8YiSIeouEIyt9i8TdQ85-Q",
"refreshToken":"64924e629bc5923172dec8fca019fba9"
}
}
3.3 调用具体API接口
按照具体API接口文档中的描述进行接口调用,调用时参考 3.1 OAuth2.0鉴权方式-请求头 描述传递请求头。