# 步骤二:JSAPI 调用(可选)
如果你的网页(Web)应用需要调用JSAPI,除了 requestAuthCode、closeWindow 、webview相关API ,其它所有调用 JSAPI 的页面均需要开发者先鉴权再调用。请参考本步骤进行配置与开发。
注意:
- 接入方前端调用 JSAPI 前的鉴权过程需要接入方服务端配合。建议你合理安排前端和服务端开发人员共同参与。
- 接入方前端只能调用 JSAPI,如果你需要调用服务端API,请在接入方服务端调用,参考如何调用服务端API。
# 鉴权流程时序图
网页应用的鉴权是从应用页面发起的,若前端页面调用需鉴权的 JSAPI 方法,在页面加载的时候就需要向服务端发起请求获取鉴权参数(appId、timestamp、nonceStr、signature),依据这些参数调用 config 接口进行鉴权,鉴权成功后即可调用 JSAPI。
# 1. 准备工作 - 开发者后台 (opens new window)配置
设置可信域名:为了BossHi客户端内网页应用的安全可信,仅可信域名内的 HTML 网页可以调用 JSAPI 获取数据,因此首先需要配置可信域名。
打开开发者后台 (opens new window),点击左侧菜单栏登录与安全,在H5可信域名中添加需要调用 JSAPI 接口的页面所在域名。配置示例见下表:
需要调用 JSAPI 接口的完整页面URL | 应在【安全设置 - H5可信域名】 中填写的页面所在域名 |
---|---|
http://10.0.147.21 | http://10.0.147.21 |
https://www.example.com/path/to/myfile.html | https://www.example.com |
https://www.example.com/path/to/myfile.html?key1=value1&key2=value2 | https://www.example.com |
https://www.example.com/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument | https://www.example.com |
https://www.example.com/path/to/myfile.html#SomewhereInTheDocument | https://www.example.com |
# 2. 接入方服务端
接入方服务端负责给接入方前端传输appId、签名等信息。
# 2.1 获取 access_token
调用服务端 API 获取应用资源时,需要通过 access token 来判断调用者身份。
- 企业自建应用:可通过 获取 tenant_access_token(企业自建应用)接口获取。
"app_id"与"app_secret"两个参数可在 开发者后台 (opens new window) > 应用基础信息 中查看。
注意:
access_token 是有有效期的,所以开发者需要在自己的服务端及时刷新凭证,以防止过期。access_token 有效期为 2 小时,再次调用 获取 tenant_access_token(企业自建应用)接口:若 access_token 剩余有效时间大于半小时,接口返回的 access_token 和旧的 access_token 值相同,且不续期;若 access_token 剩余有效时间小于半小时,接口返回一个新的 access_token,与此同时旧的 access_token 依然有效,到其原定期限过期。
示例代码:
待补充
# 2.2 获取 jsapi_ticket
jsapi_ticket 可利用上述获取的 access_token 通过 JSAPI 临时授权凭证 接口获得。
示例代码:
待补充
注意:
- 应用获取的 jsapi_ticket 是有有效期的,其有效期为 2 小时。再次调用 JSAPI 临时授权凭证 接口:若 jsapi_ticket 剩余有效时间大于半小时,接口返回的 jsapi_ticket 和旧的 jsapi_ticket 值相同,且不续期;若 jsapi_ticket 剩余有效时间小于半小时,接口返回一个新的 jsapi_ticket,与此同时旧的 jsapi_ticket 依然有效,到其原定期限过期。
- 由于获取 jsapi_ticket 的 api 调用次数非常有限,频繁刷新 jsapi_ticket 会导致 api 调用受限,影响自身业务,所以开发者在使用的时候需要缓存 jsapi_ticket (设置缓存过期时间为 2 小时),并不需要每次都从接口拉取。
- 若获取 jsapi_ticket 失败时,服务端返回的错误码为 99991401(errorMsg: ip %s is denied by app setting),说明当前 IP 被白名单限制。开启 IP 白名单后,所有接口请求都会检查来源 IP,仅白名单中的来源请求可以正常调用开放平台 API,拒绝指定 IP 之外的请求。排查建议:请检查 开发者后台 > 登录与安全 > IP 白名单 是否进行过配置,可以选择将当前IP添加进IP白名单中,或者关闭IP白名单。
# 2.3 生成签名并返回鉴权参数
获得 jsapi_ticket 之后,就可以生成 JSSDK 权限验证的签名了。
获取签名所需的参数如下:
参数 | 数据类型 | 描述 | 示例值 |
---|---|---|---|
noncestr | string | 随机字符串 | Y7a8KkqX041bsSwT |
jsapi_ticket | string | 上一步骤获得的 ticket | 617bf955832a4d4d80d9d8d85917a427 |
timestamp | number | 当前时间戳,毫秒级 | 1510045655000 |
url | string | 当前网页的 URL(可以为本地局域网网址),不包含 # 及其后面部分 | https://histatic.zhipin.com/front/bzmp-webview-h5-default/test/index.html |
签名生成规则如下:
将所有待签名参数按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串 verifyStr。对拼成的字符串 verifyStr 做 sha1 加密,得到签名 signature。
示例:
- 根据 jsapi_ticket、noncestr、timestamp、url 的顺序拼接成字符串 verifyStr:
jsapi_ticket=617bf955832a4d4d80d9d8d85917a427&noncestr=Y7a8KkqX041bsSwT×tamp=1510045655000&url=https://m.haiwainet.cn/ttc/3541093/2018/0509/content_31312407_1.html
- 对 verifyStr 进行 sha1 签名,得到 signature:
2ee6a79c182eeec8d76e7474136edb6e617b8d58
提示
- 出于安全考虑,开发者必须在服务器端实现签名的逻辑。
- 拼接字符串 verifyStr 的所有参数名均为小写字符。
- 字段名和字段值都采用原始值,不进行 URL 转义。
示例代码:
待补充
# 3. 接入方前端
接入方前端利用接入方服务端传来的数据实现 JSAPI 的鉴权,鉴权成功后即可进行 JSAPI 的调用。
# 3.1 引入 JSSDK
JSSDK 为网页应用提供了调用手机系统功能和BossHi客户端功能(如扫一扫、云文档)的能力,并支持性能优化,使你的网页应用体验能够接近原生体验。
提示
在需要调用 JSAPI 的页面引入如下 JS 文件: https://histatic.zhipin.com/front/boss-mp-web/h5sdk/h5-js-sdk-1.0.2.js
示例代码:
在 index.html 中引入JSSDK
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
<title></title>
</head>
<script src="https://cdn.bootcss.com/vConsole/3.3.4/vconsole.min.js"></script>
<script>
var vConsole = new VConsole();
</script>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
<script type="text/javascript" src="https://histatic.zhipin.com/front/boss-mp-web/h5sdk/h5-js-sdk-1.0.2.js"></script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
引入 JSSDK 会得到两个全局变量 h5sdk 以及 bz。
注意:
- 只有在BossHi应用内打开才会注入全局变量,在其他应用(比如外部浏览器网页)内打开则不会注入。因此,开发者的网页仅可在BossHi应用内成功调用JSAPI。
- JS 文件版本在升级功能时地址会变化,如有需要(比如使用新增的 API),请重新引用该文档中的JSSDK链接,确保你当前使用的JSSDK版本是最新的。
# 3.2 调用 config 接口进行 JSAPI 鉴权
利用服务端传来的 appId、timestamp、nonceStr、signature 字段,即可调用 config 接口进行 JSAPI 鉴权。
如果鉴权校验失败,除了可在 onFail 中进行失败回调的处理,也可在 h5sdk.error 接口中处理(请在调用config接口前完成)。
示例代码:
apiAuth 函数实现了 JSAPI的鉴权和调用(JSAPI调用的详情请参见流程3.3)
const lang = window.navigator.language;
$("document").ready(apiAuth());
function apiAuth() {
console.log("start apiAuth");
if (!window.h5sdk) {
console.log("invalid h5sdk");
alert("please open in BossHi");
return;
}
// 调用config接口的当前网页url
const url = encodeURIComponent(window.location.origin + window.location.pathname);
// 向接入方服务端发起请求,获取鉴权参数(appId、timestamp、nonceStr、signature)
fetch(`/get_config_parameters?url=${url}`)
.then((response) =>
response.json().then((res) => {
console.log("get_signature", res);
// 通过error接口处理API验证失败后的回调
window.h5sdk.error((err) => {
throw ("h5sdk error:", JSON.stringify(err));
});
// 调用config接口进行鉴权
window.h5sdk.config({
appId: res.appid,
timestamp: res.timestamp,
nonceStr: res.noncestr,
signature: res.signature,
jsApiList: [],
//鉴权成功回调
onSuccess: (res) => {
console.log(`config success: ${JSON.stringify(res)}`);
},
//鉴权失败回调
onFail: (err) => {
throw `config failed: ${JSON.stringify(err)}`;
},
});
// 完成鉴权后,便可在 window.h5sdk.ready 里调用 JSAPI
window.h5sdk.ready(() => {
// window.h5sdk.ready回调函数在环境准备就绪时触发
// 调用 getUserInfo API 获取已登录用户的基本信息
bz.getUserInfo({
// getUserInfo API 调用成功回调
success(res) {
console.log(`getUserInfo success: ${JSON.stringify(res)}`);
// 单独定义的函数showUser,用于将用户信息展示在前端页面上
showUser(res.userInfo);
},
// getUserInfo API 调用失败回调
fail(err) {
console.log(`getUserInfo failed, err:`, JSON.stringify(err));
},
});
// 调用 showToast API 弹出全局提示框。
bz.showToast({
title: "鉴权成功",
icon: "success",
duration: 3000,
success(res) {
console.log("showToast 调用成功", res.errMsg);
},
fail(res) {
console.log("showToast 调用失败", res.errMsg);
},
complete(res) {
console.log("showToast 调用结束", res.errMsg);
},
});
});
})
)
.catch(function (e) {
console.error(e);
});
}
function showUser(res) {
// 展示用户信息
// 头像
$("#img_div").html(
`<img src="${res.avatarUrl}" width="100%" height=""100%/>`
);
// 名称
$("#hello_text_name").text(
lang === "zh_CN" || lang === "zh-CN"
? `${res.nickName}`
: `${res.i18nName.en_us}`
);
// 欢迎语
$("#hello_text_welcome").text(
lang === "zh_CN" || lang === "zh-CN" ? "欢迎使用BossHi" : "welcome to BossHi"
);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
注意:
- 调用 config 接口的当前网页URL 的建议写法:
const url = encodeURI(window.location.origin + window.location.pathname)
。请勿写为固定值。 - config 接口中的 appId、timestamp、nonceStr、signature 参数必须直接来自服务端,不能直接在前端定义。
- config 接口内的 nonceStr 参数名使用驼峰式命名法。
- config 接口内的 nonceStr、timestamp 参数必须与服务端生成签名时的 noncestr、timestamp 参数保持一致。
# 3.3 调用 JSAPI
完成鉴权后,便可在 window.h5sdk.ready 里调用 JSAPI。
接口约定:
- 所有接口都为异步;
- 除特殊说明外(如:requestAuthCode),所有接口均需要鉴权成功后使用;
- 所有接口除特殊说明外(如:requestAuthCode)必须在 window.h5sdk.ready(function(){}) 回调函数触发后调用;
- 接受一个 object 类型的参数;
- 成功回调 success;
- 失败回调 fail。
window.bz.方法({
参数1:'',
参数2:'',
success: function(result) {
// 成功回调
},
fail: function(error) {
// 失败回调
}
})
2
3
4
5
6
7
8
9
10
代码示例:
在apiAuth函数中的 window.h5sdk.ready 函数里实现 JSAPI 的调用。(完整代码可见上一步 3.2调用 config 接口进行 JSAPI 鉴权)
# 附录
config 接口常见问题与排查建议
不管使用什么方式,比如前端console、端侧日志等,先拿config接口的Response,根据Response中的错误码,采取相应的处理措施。
待补充
错误码 | 描述 | 排查建议 |
---|