接入步骤
- 迅联云创建公司,并提供 appkey,appSecret
通用appKey: Kingxunlian.CommonTwoLeg 通用appSecret:ODc3ZDYwMDQ4ZWY4NGVjMjg0OTAzYTViZWE0Y2Y0MmY=
- 客户登录公司,激活应用:“API对接”。得到tokenKey,tokenSecret。
- 接入方拿到 appkey,appSecret,tokenKey,tokenSecret。
- 按下面方法构造 Authorization,添加到每次请求的header中,调用api。
前置说明
本文档将以一个例子,说明如何接入迅联平台开放API
访问例子接口:GET https://api.dev.kingxunlian.com/plat/company/current-user/get
提前准备
参数名 | 说明 | 来源 | 对应Oauth参数(需编码转化) |
---|---|---|---|
appKey | 应用Key | 迅联提供 | oauth_consumer_key |
appSecret | App秘钥 | 迅联提供 | oauth_consumer_secret |
tokenKey | 在迅联平台注册的公司的授权Key | 公司激活对应应用后生成 | oauth_token |
tokenSecret | 在迅联平台注册的公司的的授权秘钥 | 公司激活对应应用后生成 | oauth_token_secret |
- 相关算法说明
简写 | 名称 | 说明 |
---|---|---|
url.encode | URL编码 | 可将字符串以URL编码 |
url.decode | URL解码 | 本函数对字符串进行URL解码 |
base64.encode | base64编码 | Base64就是一种基于64个可打印字符来表示二进制数据的方法 |
base64.decode | base64解码 | Base64就是一种基于64个可打印字符来表示二进制数据的方法 |
HmacSHA256 |
目的
访问 GET https://api.dev.kingxunlian.com/plat/company/current-user/get
参数如下:
参数key | 参数value获取方法 | 本次value | 说明 |
---|---|---|---|
oauth_consumer_key | url.encode(appKey) | OAUTH.2LEGGED.APP | 应用的唯一Key标记 |
oauth_token | url.encode(tokenKey) | M2EyZDU2ZjM0ZDQ3NDFjZmIzYTliNzJkYmU2MjA1NjA%3D | 在迅联平台注册的公司的授权Key标记 |
oauth_signature_method | HMAC-SHA256 | HMAC-SHA256 | 签名方法 “HMAC-SHA256” |
oauth_timestamp | url.encode(“时间戳”) | 1554281731 | 时间戳(秒) |
oauth_nonce | url.encode(“随机字符串”) | JObPuLS38Mp | 单次值,随机生成32位字符串,防止重放攻击(每次请求必须不同) |
oauth_version | 1.0 | 1.0 | 版本号,必须为”1.0” |
oauth_signature | 待生成 | 待生成 |
方法
一、获取签名
- 第一步:构造待签名源串.
获取请求方法
GET
对请求的URL进行URL编码,即url.encode(url),得到:
https%3A%2F%2Fapi.dev.kingxunlian.com%2Fplat%2Fcompany%2Fcurrent-user%2Fget
将参数按下列顺序排列,
oauth_consumer_key,oauth_nonce,oauth_signature_method,oauth_timestamp,oauth_token,oauth_version
排序后的参数及值 [ key=value ]用“&”拼接,然后进行URL编码,得到:
oauth_consumer_key%3DOAUTH.2LEGGED.APP%26oauth_nonce%3DJObPuLS38Mp%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1554281731%26oauth_token%3DM2EyZDU2ZjM0ZDQ3NDFjZmIzYTliNzJkYmU2MjA1NjA%253D%26oauth_version%3D1.0
将 1的结果 + “&” + 2的结果 + “&” + 3的结果,形成带签名的字符串
得到:GET&https%3A%2F%2Fapi.dev.kingxunlian.com%2Fplat%2Fcompany%2Fcurrent-user%2Fget&oauth_consumer_key%3DOAUTH.2LEGGED.APP%26oauth_nonce%3DJObPuLS38Mp%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1554281731%26oauth_token%3DM2EyZDU2ZjM0ZDQ3NDFjZmIzYTliNzJkYmU2MjA1NjA%253D%26oauth_version%3D1.0
- 第二步:构造秘钥
将 url.encode(appSecret) + “&” + url.encode(tokenSecret),得到第二步结果,秘钥
MzE4ODJjNThiMDE5NDE4MDg0YmQ3NGVlNDVjNTJkNWY%3D&YjllZmEzYWU2NjM4NDUwOTk3ODU2YWRjNWM2YmE3MGY%3D
- 第三步:生成签名值
使用HMAC-SHA256加密算法(可百度),将第一步中的到的字符串用第二步中得到的密钥进行加密。
然后将加密后的字符串经过Base64编码,即得到 “oauth_signature” 签名参数的值。得到:
eLs2OgUDzoawLHmuiw42a0pdtVPsb895sQT0DDMd8SU%3D
二、构造请求
最终可以得到下列完整参数
oauth_consumer_key OAUTH.2LEGGED.APP
oauth_token M2EyZDU2ZjM0ZDQ3NDFjZmIzYTliNzJkYmU2MjA1NjA%3D
oauth_signature_method HMAC-SHA256
oauth_timestamp 1554281731
oauth_nonce JObPuLS38Mp
oauth_version 1.0
oauth_signature eLs2OgUDzoawLHmuiw42a0pdtVPsb895sQT0DDMd8SU%3D
将上述参数(key=”value”)(注意此处的引号)并用逗号,拼接起来,并在前面增加”OAuth “(注意此处的空格),可获得字符串
OAuth oauth_consumer_key="OAUTH.2LEGGED.APP",oauth_token="M2EyZDU2ZjM0ZDQ3NDFjZmIzYTliNzJkYmU2MjA1NjA%3D",oauth_signature_method="HMAC-SHA256",oauth_timestamp="1554281731",oauth_nonce="JObPuLS38Mp",oauth_version="1.0",oauth_signature="eLs2OgUDzoawLHmuiw42a0pdtVPsb895sQT0DDMd8SU%3D"
三、调用
将此字符串写入http请求 Header的 “Authorization”字段中即可.
完整示例
示例
String url = "https://api.dev.kingxunlian.com/plat/company/current-user/get";
String authStr = Utils.generatorAuthStr("GET",url);
Request sendRequest = new Request.Builder()
.url(url)
.addHeader("Authorization", authStr).get().build();
Response sendResponse = okHttpClient.newCall(sendRequest).execute();
工具类
package com.kingxunlian.sdk;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
/**
* @author martinwu
* @date 2019/6/28 15:44
*/
public class Utils {
private static final String CHARSET_NAME = "UTF-8";
public static final String MAC_NAME = "HmacSHA256";
public static String generatorAuthStr(String methodType1,String url1 ) {
//接口方法
String methodType = methodType1;
//请求url
String url = url1;
//准备参数 (使用的时候,替换这些参数)
String appKey = "Kingxunlian.CommonTwoLeg";
String appSecret = "YzNhZWIzNzBhMGQwNGVmNzg2NGI3MzUxOGI5MDI0Nzg=";
String tokenKey = "ZjZiYjgwNmI0N2NmNDkzMmE4YjJhZmMyOTM4OGVhOTQ=";
String tokenSecret = "MTEwYjU5NDg5YTQ0NDhiMmI5YjY5ZDU0ZjNlMTQwM2M=";
String signMethod = "HMAC-SHA256";
String version = "1.0";
String timestamp = System.currentTimeMillis()/1000+"";
String seqNo = UUID.randomUUID().toString().replace("-","");
/**
* 开始加密过程
* 一 .获取签名
*/
//1.获取请求方法
String step1 = methodType;
//2.对请求的URL进行URL编码,即url.encode(url)
String step2 = encodeUrlUTF8(url);
//3.参数按下列顺序排列,
//oauth_consumer_key=url.encode(appKey),
//oauth_nonce=url.encode(seqNo)
//oauth_signature_method=url.encode(signMethod),
//oauth_timestamp=url.encode(timestamp),
//oauth_token=url.encode(tokenKey),
//oauth_version=url.encode(version),
// 排序后的参数及值 [ key=value ]用“&”拼接,然后进行URL编码,得到:
StringBuilder stringBuilder = new StringBuilder();
if (StringUtils.isNotEmpty(appKey)) {
stringBuilder.append("oauth_consumer_key="+encodeUrlUTF8(appKey));
}
if (StringUtils.isNotEmpty(seqNo)) {
stringBuilder.append("&oauth_nonce="+encodeUrlUTF8(seqNo));
}
if (StringUtils.isNotEmpty(signMethod)) {
stringBuilder.append("&oauth_signature_method="+encodeUrlUTF8(signMethod));
}
if (StringUtils.isNotEmpty(timestamp)) {
stringBuilder.append("&oauth_timestamp="+encodeUrlUTF8(timestamp));
}
if (StringUtils.isNotEmpty(tokenKey)) {
stringBuilder.append("&oauth_token="+encodeUrlUTF8(tokenKey));
}
if (StringUtils.isNotEmpty(version)) {
stringBuilder.append("&oauth_version="+encodeUrlUTF8(version));
}
String kVs = stringBuilder.toString();
String step3 = encodeUrlUTF8(kVs);
//4.将 1的结果 + “&” + 2的结果 + “&” + 3的结果,形成带签名的字符串
String oStr = step1 + "&" + step2 + "&" + step3;
/**
* 二、构造秘钥
* url.encode(appSecret) + “&” + url.encode(tokenSecret)
*/
String signKey = encodeUrlUTF8(appSecret) +"&" + encodeUrlUTF8(tokenSecret);
/**
* 三、生成签名值
* 使用HMAC-SHA256加密算法,将第一步中的到的字符串oStr用第二步中得到的密钥signKey进行加密。
* 然后将加密后的字符串经过Base64编码,即得到 “oauth_signature” 签名参数的值。得到:
*/
String oauth_signature = sign(oStr,signKey);
/**
* 构造请求
* oauth_consumer_key OAUTH.2LEGGED.APP
* oauth_token M2EyZDU2ZjM0ZDQ3NDFjZmIzYTliNzJkYmU2MjA1NjA%3D
* oauth_signature_method HMAC-SHA256
* oauth_timestamp 1554281731
* oauth_nonce JObPuLS38Mp
* oauth_version 1.0
* oauth_signature eLs2OgUDzoawLHmuiw42a0pdtVPsb895sQT0DDMd8SU%3D
* 将上述参数(key=”value”)(注意此处的引号)并用逗号,拼接起来,并在前面增加”OAuth “(注意此处的空格),可获得字符串
*/
StringBuilder sb = new StringBuilder();
sb.append("OAuth ");
sb.append("oauth_consumer_key=");
sb.append("\"" + encodeUrlUTF8(appKey) + "\",");
sb.append("oauth_token=");
sb.append("\"" + encodeUrlUTF8(tokenKey) + "\",");
sb.append("oauth_signature_method=");
sb.append("\"" + encodeUrlUTF8(signMethod) + "\",");
sb.append("oauth_timestamp=");
sb.append("\"" + encodeUrlUTF8(timestamp) + "\",");
sb.append("oauth_nonce=");
sb.append("\"" + encodeUrlUTF8(seqNo) + "\",");
sb.append("oauth_version=");
sb.append("\"" + encodeUrlUTF8(version) + "\",");
sb.append("oauth_signature=");
sb.append("\"" + encodeUrlUTF8(oauth_signature) + "\"");
String authorization = sb.toString();
return authorization;
}
public static String encodeUrlUTF8(String str) {
try {
return URLEncoder.encode(str,"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
private static String sign(String toSign, String secret) {
try {
Mac mac = Mac.getInstance(MAC_NAME);
Key key = new SecretKeySpec(secret.getBytes(CHARSET_NAME), MAC_NAME);
mac.init(key);
byte[] signData = mac.doFinal(toSign.getBytes(CHARSET_NAME));
return Base64.encodeBase64String(signData);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException | InvalidKeyException e) {
e.printStackTrace();
throw new RuntimeException("加密错误");
}
}
}
文档更新时间: 2019-11-18 14:12 作者:admin