You need to enable JavaScript to run this app.
文档中心
增长分析 DataFinder

增长分析 DataFinder

复制全文
下载 pdf
OpenAPI
调用方式
复制全文
下载 pdf
调用方式

增长分析(即DataFinder) 所有开放接口,均建议使用 https 进行通信。所有接口都需要经过统一的签名处理。为了方便集成和使用,DataFinder提供了 SDK,本文为您介绍DataFinder开发接口的签名机制和使用说明。

服务地址

OpenAPI 的服务地址在不同部署环境中是隔离不互通的,您需要根据所使用的DataFinder的环境类型进行设置。

  • SaaS-云原生(含国内、海外柔佛地域)、SaaS-非云原(国内地域):https://analytics.volcengineapi.com
  • SaaS-非云原生的海外环境(BytePlus环境): https://analytics.byteplusapi.com
  • 私有化部署:根据私有化部署的环境来获取,即产品的域名地址。

说明

如果您不确定您当前的环境是哪种环境,可参考文档进行查看确认:SaaS云原生/非云原生&私有化环境

签名机制

OpenAPI 使用 AK/SK 认证鉴权。

1. 获取AK/SK

  • SaaS环境:您需要提交工单联系火山引擎技术申请获取AK/SK,申请通过后,AK/SK会发送到您的火山账号绑定的安全邮箱中,您可以前往邮箱查看,收到AK/SK后请务必妥善保管和使用。
  • 私有化环境:集团管理可在右上角“集团项目概览”(如图所示)中,创建或者重置AK/SK。

    说明

    AK是平台为每个集团默认创建的;SK为每个用户唯一,不允许自行输入,请获取后妥善保管。

    Image

2. 签名说明

AK/SK认证就是使用AK/SK对请求进行签名,在请求时将签名信息添加到消息头,从而通过身份认证。

  • AK(Access Key ID):访问密钥ID。与私有访问密钥关联的唯一标识符;访问密钥ID和私有访问密钥一起使用,对请求进行加密签名。
  • SK(Secret Access Key):与访问密钥ID结合使用的密钥,对请求进行加密签名,可标识发送方,并防止请求被修改。

请求发送方使用方式如下:
Image

  1. 以 “ak-v1/access_key/timestamp/expiretime"为认证字符串前缀。

    • ak-v1为版本号,用来表示一个认证字符串。
    • timestamp为代表签名生效UTC时间。
    • expiretime为签名有效期限。
  2. 使用签名算法(HmacSHA256),以认证字符串前缀为消息,secret_key为密钥,生成字符串sign_key。

  3. 把需要加密的字段放入canonicalRequest,其格式为:

    CanonicalRequest =
        HTTPMethod:${method} + '\n' +
        CanonicalURI:${uri} + '\n' +
        CanonicalQueryString:${queryString} + '\n' +
        CanonicalBody:${body}
    

    使用签名算法(HmacSHA256),以canonicalRequest为消息,sign_key为密钥,生成字符串signature。

  4. 最终的认证字符串为 “ak-v1/access_key/timestamp/expiretime/signature”。

  5. 把认证字符串放在http的header:Authorization:ak-v1/access_key/timestamp/expiretime/signature

使用说明

1.概述

为了方便客户调用 OpenAPI, DataFinder提供了 OpenAPI SDK, 其主要功能是提供了对签名过程和复杂查询参数的包装。SDK 已经在 Github 上开源,建议使用Github 源码的方式。基本使用流程:

  1. 根据ak, sk, API 服务地址初始化一个RangersClient (后文会使用bc来指一个RangersClient实例)
  2. 使用RangersClient的request接口来调用 API
ak = '{使用AK替换}'
sk = '{使用SK替换}'

# saas 
bc = RangersClient(ak, sk)

# 海外使用非中国区的地址;私有化,需要制定下私有化的finder服务域名,请参考 “OpenAPI 概览”的服务地址说明。
url = '{使用非中国区或者Finder服务域名替换}'
bc = RangersClient(ak, sk, url=url)

# 调用具体的接口
bc.request("${path}",...)

相关接口说明(具体的方法名称在不同的语言上会有命名格式的区别)

  • bc.data_finder("${path}", ...), 相当于 bc.request("/datafinder/${path}", ...),即在path前,加上一个/datafinder的context-path
  • bc.data_rangers("${path}", ...), 相当于bc.request(/datarangers/${path}", ...),即在path前,加上一个/datarangers的context-path
  • bc.data_tester("${path}", ...), 相当于 bc.request("/datatester/${path}", ...),即在path前,加上一个/datatester的context-path
  • bc.data_profile("${path}", ...), 相当于 bc.request("/dataprofile/${path}", ...),即在path前,加上一个/dataprofile的context-path
  • bc.data_tracer("${path}", ...), 相当于 bc.request("/datatracer/${path}", ...),即在path前,加上一个/datatracer的context-path

建议后续都使用bc.request接口
另外,OpenAPI 还提供了查询 DSL Builder,具体接口参考源码 API 说明。

2.Java

  • 源码:https://github.com/volcengine/datafinder-sdk-openapi-java
  • 软件包:https://github.com/volcengine/datafinder-sdk-openapi-java/raw/main/release/sdk-openapi-java.zip
  • 初始化示例:
String ak = "xxx";
String sk = "xxx";

// SDK 的默认url地址是指向中国区 SAAS 的
RangersClient bc = new RangersClient(ak, sk);

// 海外和私有化需要指定url地址, 可以参考 “OpenAPI 概览”
String url="{使用非中国区或者Finder服务域名替换}";
RangersClient bc = new RangersClient(ak, sk, url);

3.Python

  • 源码:https://github.com/volcengine/datafinder-sdk-openapi-py
  • 软件包:https://github.com/volcengine/datafinder-sdk-openapi-py/raw/main/release/rangersdk-1.2.0.tar.gz

Python SDK 软件包的形式下载后在shell执行以下命令完成安装:

# python需要3.7及以上版本
pip install rangersdk-${version}.tar.gz
  • 初始化示例:
from rangersdk import RangersClient

ak = 'xxx' # ak
sk = 'xxx' # sk
bc = RangersClient(ak, sk)

# 海外和私有化需要指定url地址, 可以参考 “OpenAPI 概览”,
url = '{使用非中国区或者Finder服务域名替换}'
# 注意这里传参数,一定要写成 url=url
bc = RangersClient(ak, sk, url=url)

4.Js

  • 源码:https://github.com/volcengine/datafinder-sdk-openapi-js
  • 软件包:https://github.com/volcengine/datafinder-sdk-openapi-js/raw/main/release/nodejssdk.zip
  • 初始化示例:
ak = "xxx"
sk = "xxx"
bc = new RangersClient(ak, sk)

// 海外和私有化需要指定url地址, 可以参考 “OpenAPI 概览”
url = '{使用非中国区或者Finder服务域名替换}'
bc = RangersClient(ak, sk, url=url)

5.Golang

  • 源码:https://github.com/volcengine/datafinder-sdk-openapi-go
  • 软件包:https://github.com/volcengine/datafinder-sdk-openapi-go/raw/main/release/gosdk.zip
  • 初始化示例:
var (
   ak = "xxx"
   sk = "xxx"
)
bc := dslcontent.NewRangersClient(ak, sk)

// 海外和私有化需要指定url地址, 可以参考 “OpenAPI 概览”
url = '{使用非中国区或者Finder服务域名替换}'
bc := dslcontent.NewRangersClientWithUrl(ak, sk, url)

6.PHP

  • 源码:https://github.com/volcengine/datafinder-sdk-openapi-php
  • 软件包:https://github.com/volcengine/datafinder-sdk-openapi-php/raw/main/release/phpsdk.zip
  • 初始化示例:
ak = "xxx";
sk = "xxx";
$bc = new RangersClient($ak, $sk);

// 海外和私有化需要指定url地址, 可以参考 “OpenAPI 概览”
$url = '{使用非中国区或者Finder服务域名替换}'
$bc = new RangersClient($ak, $sk, $url);

示例代码

这里以Java 为例,其他的语言的代码可以查看 OpenAPI SDK 里面提供的源码。

签名 (AuthUtil.java)

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

public class AuthUtils {

        /**
     * 
     * @param ak accessKey
     * @param sk secretKey
     * @param expirationSeconds 过期时间,单位秒
     * @param method 方法,GET, POST, PUT
     * @param uriPath 请求的path,非完整的url
     * @param params 请求参数
     * @param body 请求的json体
     * @return
     */
    public static String sign(String ak, String sk, int expirationSeconds, String method, String uriPath, Map<String, String> params, String body) {
        String cm = canonicalMethod(method);
        String cu = canonicalUrl(uriPath);
        String cp = canonicalParam(params);
        String cb = canonicalBody(body);
        String text = cm + "\n" + cu + "\n" + cp + "\n" + cb;
        return doSign(ak, sk, expirationSeconds, text);
    }

    private static String canonicalMethod(String method) {
        return "HTTPMethod:" + method;
    }

    private static String canonicalUrl(String url) {
        return "CanonicalURI:" + url;
    }

    private static String canonicalParam(Map<String, String> params) {
        String res = "CanonicalQueryString:";
        if (params == null || params.isEmpty()) {
            return res;
        }
        for (String key : params.keySet()) {
            res += formatKeyValue(key, params.get(key)) + "&";
        }
        return res.substring(0, res.length() - 1);
    }

    private static String formatKeyValue(String key, String value) {
        return key + "=" + value;
    }

    private static String canonicalBody(String body) {
        String res = "CanonicalBody:";
        if (body == null) {
            return res;
        } else {
            return res + body;
        }
    }

    private static String doSign(String ak, String sk, int expiration, String text) {
        String signKeyInfo = "ak-v1/" + ak + "/" + (int) (System.currentTimeMillis() / 1000) + "/" + expiration;
        String signKey = sha256Hmac(signKeyInfo, sk);
        String signResult = sha256Hmac(text, signKey);
        return signKeyInfo + "/" + signResult;
    }


    private static String sha256Hmac(String message, String secret) {
        String hash = "";
        try {
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
            hash = byteArrayToHexString(bytes);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return hash;
    }

    private static String byteArrayToHexString(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b != null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1) {
                hs.append('0');
            }
            hs.append(stmp);
        }
        return hs.toString().toLowerCase();
    }
}

调用

import java.util.LinkedHashMap;
import java.util.Map;

public class AuthGenDemo {

    //分配的accessKey和secretKey
    private static String accessKey = "****";
    private static String secretKey = "****";
    // 单位秒
    private static Integer expirationSeconds = 300;

    public static void main(String[] args) {
        String method = "POST";
        // 请求的path,非完整的url
        String uri = "/dataprofile/openapi/v1/751/users/185";
        Map<String, String> exampleQueryParams = new LinkedHashMap<>();
        exampleQueryParams.put("set_once", "true");
        String exampleQueryBodyJson = "{\"name\":\"name\",\"value\":\"zhangsan\"}";

        String authorization = AuthUtils.sign(accessKey, secretKey, expirationSeconds,
                method, uri, exampleQueryParams, exampleQueryBodyJson);
        System.out.println("authorization: " + authorization);
    }
}

FAQ

Q1:调用OpenAPI时报错,'code': 400, 'message': 'signature expired'

此类报错错误通常是由于签名过期导致的。这种情况可能有以下几种原因:

可能原因

解决方案

时间不同步。
服务器和客户端的时间不同步,导致签名生成的时间戳与服务器验证的时间戳不一致。

确保两台机器的系统时间是同步的,可以使用NTP(网络时间协议)进行时间同步。

签名有效期过短。
签名的有效期设置得太短,导致在请求到达服务器时签名已经过期。

检查签名生成时设置的有效期参数,确保其足够长。

请求延迟。
网络延迟或其他原因导致请求在传输过程中耗时过长,超过了签名的有效期。

可以尝试增加签名的有效期。

签名生成错误。
签名生成过程中可能存在错误,导致生成的签名不正确。

检查签名生成的代码逻辑,确保其正确无误。

最近更新时间:2025.04.21 17:46:50
这个页面对您有帮助吗?
有用
有用
无用
无用