文档首页/ Astro大屏应用 AstroCanvas/ 用户指南/ AstroCanvas学堂/ AstroCanvas分享页Token签名校验使用说明
更新时间:2024-12-05 GMT+08:00
分享

AstroCanvas分享页Token签名校验使用说明

通过Token参数签名校验功能,可以对大屏交互时传递的URL进行签名鉴权,保证大屏的URL访问链接不会被篡改,从而提高大屏数据以及用户信息的安全性。

前提条件

在使用Token签名验证功能前,需满足以下条件:

  • AstroCanvas大屏页面,使用Token验证的方式进行发布。
  • AstroCanvas大屏页面,以Get的方式在URL中传递参数,且必须带有_dmax_signature、_dmax_time参数。
  • AstroCanvas大屏URL未被篡改。

背景信息

用户开启了Token签名验证功能,系统返回用以生成签名的Token(用于生成签名的token不可公开),例如token=j5TZLK1DQ*****Ntquo/ErqonR0=。

假设,某用户系统嵌入了AstroCanvas大屏页面,通过Token计算签名,最终得到的分享页面链接为(如果对该分享链接进行了篡改,那么页面将无法访问):

https://dmax.***.com/magno/render/share/xxx?_dmax_time=1669621495545&name=cloud&age=36&dept=cloud&_dmax_signature=DVX7Qy******o5rs%3D

其中:

  • _dmax_time=1669621495545:为AstroCanvas页面用户分享链接生成时间戳。如果开启了有效期设置,_dmax_time值要小于有效期值,单位为毫秒时间戳。
  • _dmax_signature=DVX7Qy******o5rs%3D:为Token对URL进行计算得出的签名,用于身份验证。
  • name=cloud&age=36&dept=cloud:为用户自定义扩展参数。

分享URL签名说明

Token签名校验,是针对整个URL计算并得出的签名。其中,“_dmax_time”为签名生成时的时间戳(该参数值可自定义,默认为计算签名时的时间)。“_dmax_signature”为最终对URL进行计算得出的签名。

在计算签名时,会对参数按照key升序排序,且将多个相同key的参数值进行合并。

例如,用于计算签名的URL输入如下:

https://dmax.***.com/magno/render/share/xxx?_dmax_time=1669621495545&name=cloud&age=35&dept=cloud&age=36

则通过对参数排序,相同参数合并后(例如age),得到的用于计算的URL为:

https://dmax.***.com/magno/render/share/xxx?_dmax_time=1669621495545&age=35,36&dept=cloud&name=cloud

URL签名计算代码示例

以Java代码为例,URL签名计算代码示例如下:

private String getSignature(String uri, TreeMap<String, String[]> parameterMap, String token) {
        List<String> parameterList = parameterMap.entrySet()
            .stream()
            .map(entry -> entry.getKey() + "=" + String.join(",", entry.getValue()))
            .collect(Collectors.toList()); // 对参数进行排序
        String sortParams = String.join("&", parameterList); // 重新拼接参数
        String usedSigUrl = String.join("?", new String[] {uri, sortParams});
        String signature = Objects.requireNonNull(
            HMACSHA256(usedSigUrl.getBytes(StandardCharsets.UTF_8), token.getBytes(StandardCharsets.UTF_8)));
        return signature;
    }
    private String HMACSHA256(byte[] data, byte[] key) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA256");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(signingKey);
            return URLEncoder.encode(byte2Base64(mac.doFinal(data)), StandardCharsets.UTF_8.name());
        } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }
    private String byte2Base64(byte[] bytes) {
        return Base64.encodeBase64String(bytes);
    }
    public void getSignatureUrl() {
        String cusUrl = "https://dmax.test.com/magno/render/share/xxx?name=cloud&age=36&dept=cloud"; // 待签名计算url
        String uri = "https://dmax.test.com/magno/render/share/xxx"; // uri
        String token = "xxxx"; // 页面分享认证token
        String timestamp = String.valueOf(new Date().getTime()); // 时间戳
        TreeMap<String, String[]> parameterMap = new TreeMap<>(); // 参数集合
        parameterMap.put("name", new String[] {"cloud"});
        parameterMap.put("age", new String[] {"36"});
        parameterMap.put("dept", new String[] {"cloud"});
        parameterMap.put("_dmax_time", new String[] {timestamp});
        String signature = getSignature(uri, parameterMap, token);
        String inputUrl = cusUrl + "&" + "_dmax_time=" + timestamp; // 将分享链接url拼接上时间戳参数
        System.out.println(String.join("&", inputUrl, "_dmax_signature=" + signature)); // 打印输出
    }

使用以上代码示例,得到的可访问签名的分享链接为:

https://dmax.***.com/magno/render/share/xxx?name=cloud&age=36&dept=cloud&_dmax_time=1669639799495&_dmax_signature=2Lbxef1HvbIx4kd9pBjmHswAa******xlBu3o9M%3D

在URL有效期内,如果篡改了该URL任何一处,链接将无法访问。

相关文档