跳到主要内容

身份认证

Datadata API 依赖 API-Token 进行身份验证,API-Token 由 AccessKey 和通过 SecretKey 加密的 Payload 组成, 本章将详细介绍 SecretKey 的获取方式和对 Payload 的加密步骤。

创建您的 API-Key

提示

API-Key 由 AccessKey 和 SecretKey 两部分组成。

要生成新的 API-Key,请登录后点击顶部导航的用户头像,选择用户设置 -> API -> 创建 API Key

然后输入 API-Key 名称,名称用于帮助您记忆此 API-Key 的用途,点击确定后,您就可以看到当前 API-Key 对应的 AccessKey 和 SecretKey 了。

API-Keys

危险

AccessKey 是公开的,用户区分用户身份;SecretKey 是私密的,用于加密 Payload 数据,请妥善保管您的 SecretKey

Payload

Payload 是 API-Token 中携带的信息,其格式为 JSON,包括 3 个字段,如下。

字段类型描述
expirednumber可选。Token 过期时间,值是 Unix 时间,即自 1970 年 1 月 1 日(世界协调时)起经过的秒数。
hoststring可选。 签发此 Token 的身份,值是 Token 签发方的域名。
uidstring可选。 子用户的 UID,如果有值,则认为是子用户。

示例:

{
"uid": "007",
"host": "www.example.com",
"expired": 1741058185
}

生成 API-Token

API-Token 由两部分组成,第一部分是 AccessKey ,第二部分是使用 SecretKey 和 AES-CFB 加密算法对 Payload 加密后的密文,中间使用 . 连接。

下面是加密算法的示例代码。

提示

我们强烈建议您使用我们的SDK,以便快速集成而不用编写太多代码,访问 https://github.com/orgs/datadata-team/repositories?q=sdk 查找适合您语言的SDK。

点击此处在 Go Better PlaygroundGo Playground 上运行。

package main

import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/md5"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
)

type APITokenPayload struct {
UID string `json:"uid"`
Host string `json:"host"`
Expired uint64 `json:"expired"`
}

func PadLength(slice_length, blocksize int) (padlen int) {
padlen = blocksize - slice_length%blocksize
if padlen == 0 {
padlen = blocksize
}
return padlen
}

func PKCS7Pad(message []byte, blockSize int) (padded []byte, err error) {
if blockSize < 1<<1 {
err = errors.New("block size is too small (minimum is 2 bytes)")
return
}
if blockSize < 1<<8 {
padLen := PadLength(len(message), blockSize)

padding := bytes.Repeat([]byte{byte(padLen)}, padLen)

padded = append(message, padding...)
return padded, nil
}

err = errors.New("unsupported block size")
return
}

func Encrypt(key string, value []byte) (result string, err error) {
var hash = md5.New()

_, err = hash.Write([]byte(key))
if err != nil {
return "", err
}

var block cipher.Block
block, err = aes.NewCipher(hash.Sum(nil))
if err != nil {
return "", err
}

hash.Reset()
hash.Write(value)
value = append(value, hash.Sum(nil)...)
value, err = PKCS7Pad(value, aes.BlockSize)
if err != nil {
return "", err
}

var iv = make([]byte, aes.BlockSize)
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return "", err
}

var stream = cipher.NewCFBEncrypter(block, iv)
var ciphertext = make([]byte, len(value))
stream.XORKeyStream(ciphertext, value)

return hex.EncodeToString(append(iv, ciphertext...)), nil
}

func main() {
var err error = nil
var accessKey = "1c67be15cb6a3be5a9b86dffca7f348f"
var secretKey = "500c33c5485e4d7eb5c89dd8f33084dc"

var payload = `{ "uid": "abc", "host": "www.example.com", expired: }`

var token string
token, err = Encrypt(secretKey, []byte(payload))
if err != nil {
panic(err)
}

fmt.Printf("token: %s.%s\n", accessKey, token)
}

发起请求

完成上一步之后,我们拿到了 API-Token ,现在我们就可以开始发起 API 请求了。

发起任何 API 请求之前,我们需要将上一步获取到的 API-Token 附加到请求中,有两种方式:

  1. 将 Token 添加到 Request Header 中,这是我们推荐的方式,属性名称是 x-datadata-api-token
  2. 将 Token 添加到 Query 中,适用于您无法修改 Request Header 的情况,通常是不推荐的。属性名称是 api_token

例如,使用 Curl 发起请求,分页获取当前当前用户所有的 Charts 列表:

curl https://www.datadata.cn/api/v1/charts \
-H 'x-datadata-api-token: <your-token>'
提示

更多 API 端点请查看 API-Endpoints 章节。