身份认证
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 了。
AccessKey 是公开的,用户区分用户身份;SecretKey 是私密的,用于加密 Payload 数据,请妥善保管您的 SecretKey!
Payload
Payload 是 API-Token 中携带的信息,其格式为 JSON,包括 3 个字段,如下。
字段 | 类型 | 描述 |
---|---|---|
expired | number | 可选。Token 过期时间,值是 Unix 时间,即自 1970 年 1 月 1 日(世界协调时)起经过的秒数。 |
host | string | 可选。 签发此 Token 的身份,值是 Token 签发方的域名。 |
uid | string | 可选。 子用户的 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
- Node
点击此处在 Go Better Playground 或 Go 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)
}
点击此处在 Stackblitz 上运行。
import AES from 'crypto-js/aes';
import Hex from 'crypto-js/enc-hex';
import Utf8 from 'crypto-js/enc-utf8';
import WordArray from 'crypto-js/lib-typedarrays';
import MD5 from 'crypto-js/md5';
import CFB from 'crypto-js/mode-cfb';
import Pkcs7 from 'crypto-js/pad-pkcs7';
const accessKey = '1c67be15cb6a3be5a9b86dffca7f348f';
const secretKey = '500c33c5485e4d7eb5c89dd8f33084dc';
async function encrypt(secretKey: string, payload: string) {
const iv = WordArray.random(16);
const key = MD5(secretKey);
const value = Utf8.parse(payload).clone().concat(MD5(payload));
const encrypted = AES.encrypt(value, key, {
iv: iv,
mode: CFB,
padding: Pkcs7,
});
return iv.clone().concat(encrypted.ciphertext).toString(Hex);
}
async function main() {
const token = await encrypt(
secretKey,
JSON.stringify({ uid: 'abc', host: 'www.example.com', expired: 1710313863 })
);
console.log(`api-token: ${accessKey}.${token}`);
}
main().catch((err) => console.error(err));
发起请求
完成上一步之后,我们拿到了 API-Token ,现在我们就可以开始发起 API 请求了。
发起任何 API 请求之前,我们需要将上一步获取到的 API-Token 附加到请求中,有两种方式:
- 将 Token 添加到 Request Header 中,这是我们推荐的方式,属性名称是
x-datadata-api-token
。 - 将 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 章节。