# 步骤二:JSAPI 调用(可选)

如果你的网页(Web)应用需要调用JSAPI,除了 requestAuthCodecloseWindow 、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 来判断调用者身份。

"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&timestamp=1510045655000&url=https://m.haiwainet.cn/ttc/3541093/2018/0509/content_31312407_1.html
1
  • 对 verifyStr 进行 sha1 签名,得到 signature:
2ee6a79c182eeec8d76e7474136edb6e617b8d58
1

提示

  • 出于安全考虑,开发者必须在服务器端实现签名的逻辑。
  • 拼接字符串 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>
1
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"
  );
}
1
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) {
         // 失败回调     
    	}
})
1
2
3
4
5
6
7
8
9
10

代码示例:

在apiAuth函数中的 window.h5sdk.ready 函数里实现 JSAPI 的调用。(完整代码可见上一步 3.2调用 config 接口进行 JSAPI 鉴权)

# 附录

config 接口常见问题与排查建议

不管使用什么方式,比如前端console、端侧日志等,先拿config接口的Response,根据Response中的错误码,采取相应的处理措施。

待补充

错误码 描述 排查建议
最后更新于 : 6/8/2023, 11:26:27 AM