Skip to content
开发文档
能力中心
应用市场
WebOffice
开发者后台

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_tokenstring上一步获取的 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&timestamp=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 + "&timestamp=" + 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 + "&timestamp=" + timestamp + "&url=" + url));
    }
}

Step4 配置 H5 可信域名

前往 开发者后台

  1. 在开发者管理中,点击「安全设置」。
  2. 在「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() {
       // 失败回调
    }
});