JSAPI 鉴权流程
为了防止恶意网页通过 JSAPI 随意获取用户私密信息,对用户财产造成损失,需要确保 JSAPI 的调用方是可信任的。因此在 JSAPI 被调用前,需要通过接口进行鉴权,只有鉴权成功的情况下,JSAPI 的调用才会生效。
接入必读
- 目前协作提供的所有 JSAPI 都需要鉴权;
- 鉴权是针对 H5 页面实现的,如果当前页面用到了 JSAPI ,此页面就需要执行鉴权流程;
流程时序图
Step1 获取 jsapi_token
请求说明
请求地址 | https://openapi.wps.cn/kopen/woa/api/v1/developer/app/sdk/auth/jsapi_token |
---|---|
请求方法 | GET |
签名方式 | wps-3 |
请求地址示例
http
[GET]https://openapi.wps.cn/kopen/woa/api/v1/developer/app/sdk/auth/jsapi_token
响应体示例
json
// 成功
{
"result": 0,
"jsapi_token": "xxxxxx",
"expires_in": 7200 // 过期时间(秒)
}
// 失败
{
"result": 10801xxx,
"msg": "error msg"
}
Step2 获取 jsapi_ticket
请求说明
请求地址 | https://openapi.wps.cn/kopen/woa/api/v1/developer/app/sdk/auth/jsapi_ticket |
---|---|
请求方法 | GET |
签名方式 | wps-3 |
查询参数(Query)
名称 | 类型 | 是否必填 | 说明 |
---|---|---|---|
jsapi_token | string | 是 | 上一步获取的 jsapi_token |
请求地址示例
http
[GET]https://openapi.wps.cn/kopen/woa/api/v1/developer/app/sdk/auth/jsapi_ticket?jsapi_token=xxxx
响应体示例
json
// 成功
{
"result": 0,
"jsapi_ticket": "xxxxxx",
"expires_in": 7200 // 过期时间(秒)
}
// 失败
{
"result": 10801xxx,
"msg": "error msg"
}
Step3 计算签名
参与签名的字段包括 noncestr(随机字符串),有效的 jsapi_ticket,timestamp(时间戳), url(当前网页的 URL,需包含# ?& 等部分,即一个完整的网页 url 数据。若前端传给服务端做了编码处理,服务端需要进行解码,以保证 url 正确)。
json
noncestr=Y7a8KkqX041bsSwT // 业务方随机字符串
jsapi_ticket=617bf955832a4d4d80d9d8d85917a427 // ticket
timestamp=1510045655000 // 时间戳
url=https://m.haiwainet.cn/ttc/3541093/2018/0509/content_31312407_1.html?a=b&c=d // 当前网页url
根据 jsapi_ticket、nonceStr、timestamp、url 的顺序,使用 URL 键值对的格式(即 key1=value1&key2=value2...)拼接成字符串 verifyStr:(顺序和字段名不能改变)
json
jsapi_ticket=617bf955832a4d4d80d9d8d85917a427&noncestr=Y7a8KkqX041bsSwT×tamp=1510045655000&url=https://m.haiwainet.cn/ttc/3541093/2018/0509/content_31312407_1.html?a=b&c=d
对 verifyStr 进行 sha1 签名,得到 signature:
json
63fba76a53eb4862872741ead44731f53465d563
示例代码:
go
func main() {
noncestr := "Y7a8KkqX041bsSwT"
jsapi_ticket := "617bf955832a4d4d80d9d8d85917a427"
timestamp := "1510045655000"
url := "https://m.haiwainet.cn/ttc/3541093/2018/0509/content_31312407_1.html?a=b&c=d"
verifyStr := "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url
hash := sha1.New()
hash.Write([]byte(verifyStr))
toString := hex.EncodeToString(hash.Sum(nil))
fmt.Println(toString)
}
java
import java.security.MessageDigest;
public class main {
public static String shaEncode(String inStr) throws Exception {
MessageDigest sha = null;
try {
sha = MessageDigest.getInstance("SHA");
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
return "";
}
byte[] byteArray = inStr.getBytes("UTF-8");
byte[] md5Bytes = sha.digest(byteArray);
StringBuffer hexValue = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
int val = ((int) md5Bytes[i]) & 0xff;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}
public static void main(String[] args) throws Exception {
String noncestr = "Y7a8KkqX041bsSwT";
String jsapi_ticket = "617bf955832a4d4d80d9d8d85917a427";
String timestamp = "1510045655000";
String url = "https://m.haiwainet.cn/ttc/3541093/2018/0509/content_31312407_1.html?a=b&c=d";
System.out.println(shaEncode("jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url));
}
}
Step4 配置 H5 可信域名
前往 开发者后台
- 在开发者管理中,点击「安全设置」。
- 在「H5 可信域名」中添加需要调用 config 接口的页面所在域名。例如:完整 URL 是 http://www.xiezuo.com?type=xxxx, 则配置 http://www.xiezuo.com。
Step5 调用获取 config 接口鉴权
完成以上步骤后,应用方服务端将数据传递给应用方前端。包括以下参数:
参数 | 参数说明 |
---|---|
appID | 鉴权的应用 ID |
timeStamp | 生成签名时用到的时间戳 |
nonceStr | 生成签名时用到的随机字符串 |
signature | 生成的签名 |
业务方前端拿到数据后,在所有需要使用 JSAPI 的页面必须先注入配置信息,否则将无法调用。针对单页面应用,鉴权需要对父页面实现。
json
window.ksoxz_sdk.config({
params: {
appId: '', // 必填,应用ID
timeStamp: 0, // 必填,生成签名的时间戳,毫秒级
nonceStr: '', // 必填,生成签名的随机串
signature: '', // 必填,签名
},
onSuccess: function() {
// 成功回调
},
onError: function() {
// 失败回调
}
});