You need to enable JavaScript to run this app.
文档中心
TrafficRoute DNS 套件

TrafficRoute DNS 套件

复制全文
下载 pdf
API 参考
调用方式
复制全文
下载 pdf
调用方式

您通过 HTTP 请求来调用火山引擎云解析(DNS)的 API。

在发送 HTTP 请求前,您需要理解以下内容:

请求结构

API 请求的结构包含以下内容:

  • API 服务域名。
  • 通讯协议。
  • 请求方法。
  • 请求参数。

API 服务域名

云解析 DNS 的 API 服务域名是 dns.volcengineapi.com

通讯协议

您可以使用 HTTP 协议或 HTTPS 协议发送请求。推荐您使用 HTTPS 协议,其安全性更高。

请求方法

关于 API 所使用的方法,参见每个 API 的说明。对于 POST 请求,您必须在请求头中指定 Content-Type: application/json

请求参数

请求参数包括公共参数和每个 API 所特有的参数。

公共参数

公共参数是每个 API 请求必须包含的参数。如果一个 API 请求缺失公共参数,请求会失败。以下表格中的公共参数必须包含在查询字符串(query string)中。

参数名称数据类型是否必选说明示例
ActionStringAPI 名称。格式为 [a-zA-Z]+CreateZone
VersionStringAPI 版本。该参数的取值是 2018-08-012018-08-01
X-ExpiresInteger签名的有效时间,单位为秒。默认值为 900。900

请求鉴权的示例代码

每个请求中必须包含鉴权信息。该鉴权信息用以验证请求者的身份。

Golang 示例代码

下面的示例代码演示了如何基于 Golang 调用 UpdateZone APICheckZone API 时对请求进行鉴权。

在运行示例代码之前,您需要 获取 Access Key ID 和 Secret Access Key。然后,您需要分别将 Access Key ID 和 Secret Access Key 的值传入示例代码中的 AccessKey 常量和 SecretAccessKey 常量。

package main

import (
   "bytes"
   "crypto/hmac"
   "crypto/sha256"
   "encoding/hex"
   "encoding/json"
   "fmt"
   "io/ioutil"
   "net/http"
   "net/url"
   "strings"
   "time"
)

const Version = "2018-08-01"
const Service = "DNS"
const Region = "cn-north-1"
const Host = "dns.volcengineapi.com"

// 第一步:准备辅助函数。
// sha256非对称加密
func hmacSHA256(key []byte, content string) []byte {
   mac := hmac.New(sha256.New, key)
   mac.Write([]byte(content))
   return mac.Sum(nil)
}

// sha256 hash算法
func hashSHA256(content []byte) string {
   h := sha256.New()
   h.Write(content)
   return hex.EncodeToString(h.Sum(nil))
}

// 第二步:准备需要用到的结构体定义。
// 签算请求结构体
type RequestParam struct {
   Body      []byte
   Method    string
   Date      time.Time
   Path      string
   Host      string
   QueryList url.Values
}

// 身份证明结构体
type Credentials struct {
   AccessKeyID     string
   SecretAccessKey string
   Service         string
   Region          string
}

// 签算结果结构体
type SignRequest struct {
   XDate          string
   Host           string
   ContentType    string
   XContentSha256 string
   Authorization  string
}

// go http client
var httpClient = &http.Client{
   Timeout: time.Second * 60,
   Transport: &http.Transport{
      MaxIdleConns:    100,
      MaxConnsPerHost: 10,
      IdleConnTimeout: time.Second * 15,
   },
}

// 第三步:创建一个 DNS 的 API 请求函数。签名计算的过程包含在该函数中。
func requestDNS(method string, query map[string][]string, header map[string]string, ak string, sk string, action string, body []byte) ([]byte, error) {
   // 第四步:在requestDNS中,创建一个 HTTP 请求实例。
   // 创建 HTTP 请求实例。该实例会在后续用到。
   request, _ := http.NewRequest(method, "https://"+Host+"/", bytes.NewReader(body))
   urlVales := url.Values{}
   for k, v := range query {
      urlVales[k] = v
   }
   urlVales["Action"] = []string{action}
   urlVales["Version"] = []string{Version}
   request.URL.RawQuery = urlVales.Encode()
   for k, v := range header {
      request.Header.Set(k, v)
   }
   // 第五步:创建身份证明。其中的 Service 和 Region 字段是固定的。ak 和 sk 分别代表 AccessKeyID 和 SecretAccessKey。同时需要初始化签名结构体。一些签名计算时需要的属性也在这里处理。
   // 初始化身份证明
   credential := Credentials{
      AccessKeyID:     ak,
      SecretAccessKey: sk,
      Service:         Service,
      Region:          Region,
   }
   // 初始化签名结构体
   requestParam := RequestParam{
      Body:      body,
      Host:      request.Host,
      Path:      "/",
      Method:    request.Method,
      Date:      time.Now().UTC(),
      QueryList: request.URL.Query(),
   }
   // 第六步:接下来开始计算签名。在计算签名前,先准备好用于接收签算结果的 signResult 变量,并设置一些参数。
   // 初始化签名结果的结构体
   xDate := requestParam.Date.Format("20060102T150405Z")
   shortXDate := xDate[:8]
   XContentSha256 := hashSHA256(requestParam.Body)
   contentType := "application/json"
   signResult := SignRequest{
      Host:           requestParam.Host, // 设置Host
      XContentSha256: XContentSha256,    // 加密body
      XDate:          xDate,             // 设置标准化时间
      ContentType:    contentType,       // 设置Content-Type 为 application/json
   }
   // 第七步:计算 Signature 签名。
   signedHeadersStr := strings.Join([]string{"content-type", "host", "x-content-sha256", "x-date"}, ";")
   canonicalRequestStr := strings.Join([]string{
      requestParam.Method,
      requestParam.Path,
      request.URL.RawQuery,
      strings.Join([]string{"content-type:" + contentType, "host:" + requestParam.Host, "x-content-sha256:" + XContentSha256, "x-date:" + xDate}, "\n"),
      "",
      signedHeadersStr,
      XContentSha256,
   }, "\n")
   hashedCanonicalRequest := hashSHA256([]byte(canonicalRequestStr))
   credentialScope := strings.Join([]string{shortXDate, credential.Region, credential.Service, "request"}, "/")
   stringToSign := strings.Join([]string{
      "HMAC-SHA256",
      xDate,
      credentialScope,
      hashedCanonicalRequest,
   }, "\n")
   kDate := hmacSHA256([]byte(credential.SecretAccessKey), shortXDate)
   kRegion := hmacSHA256(kDate, credential.Region)
   kService := hmacSHA256(kRegion, credential.Service)
   kSigning := hmacSHA256(kService, "request")
   signature := hex.EncodeToString(hmacSHA256(kSigning, stringToSign))
   signResult.Authorization = fmt.Sprintf("HMAC-SHA256 Credential=%s, SignedHeaders=%s, Signature=%s", credential.AccessKeyID+"/"+credentialScope, signedHeadersStr, signature)
   // 第八步:将 Signature 签名写入HTTP Header 中,并发送 HTTP 请求。
   // 设置经过签名的5个HTTP Header
   request.Header.Set("Host", signResult.Host)
   request.Header.Set("Content-Type", signResult.ContentType)
   request.Header.Set("X-Date", signResult.XDate)
   request.Header.Set("X-Content-Sha256", signResult.XContentSha256)
   request.Header.Set("Authorization", signResult.Authorization)
   resp, err := httpClient.Do(request)
   if err != nil {
      return nil, err
   }
   body, err = ioutil.ReadAll(resp.Body)
   if err != nil {
      return nil, err
   }
   return body, nil
}

/* main.go */

// 定义请求参数结构体
type UpdateZoneParam struct {
   ZID    uint64 `json:"ZID"`
   Remark string `json:"Remark"`
}

func main() {
    // (POST 请求)调用 UpdateZone API
    bodyParam := UpdateZoneParam{
       ZID:    100,
       Remark: "example",
    }
    body, err := json.Marshal(&bodyParam)
    if err != nil {
       fmt.Printf("marshal failed: %v", err)
       return
    }

    // 分别将 Access Key ID 和 Secret Access Key 的值传入 AK 常量和 SK 常量
    AccessKey := "ak"
    SecretAccessKey := "sk"

    updateZoneResult, err := requestDNS("POST", map[string][]string{}, map[string]string{}, AccessKey, SecretAccessKey, "UpdateZone", body)
    if err != nil {
       fmt.Printf("do request failed: %v", err)
       return
    }
    // 打印输出的结果
    fmt.Println(string(updateZoneResult))

    // (GET 请求)调用 CheckZone API
    QueryParam := map[string][]string{"ZoneName": []string{"example.com"}}

    checkZoneResult, err := requestDNS("GET", QueryParam, map[string]string{}, AccessKey, SecretAccessKey,
       "CheckZone", []byte{})
    if err != nil {
       fmt.Printf("do request failed: %v", err)
       return
    }
    // 打印输出的结果
    fmt.Println(string(checkZoneResult))

}

Java 示例代码

下面的示例代码演示了如何基于 Java 调用 UpdateZone APICheckZone API 时对请求进行鉴权。

在运行示例代码之前,您需要 获取 Access Key ID 和 Secret Access Key。然后,您需要分别将 Access Key ID 和 Secret Access Key 的值传入示例代码中的 AccessKey 常量和 SecretAccessKey 常量。

import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Hex;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class MainDNS {

    // 第一步:准备需要用到的类定义。
    // 签算请求结构类
    public static class RequestParam {
        public final byte[] body;
        public final String method;
        public final Date date;
        public final String path;
        public final String host;
        public final String contentType;
        public final ArrayList<NameValuePair> queryList;

        public RequestParam(byte[] body, String method, Date date, String path, String host, String contentType, ArrayList<NameValuePair> queryList) {
            this.body = body;
            this.method = method;
            this.date = date;
            this.path = path;
            this.host = host;
            this.contentType = contentType;
            this.queryList = queryList;
        }
    }

    public static final String TIME_FORMAT_V4 = "yyyyMMdd'T'HHmmss'Z'";
    private static final TimeZone tz = TimeZone.getTimeZone("UTC");
    // 分别将 Access Key ID 和 Secret Access Key 的值传入 AK 常量和 SK 常量
    private static final String AK = "ak";
    private static final String SK = "sk";
    private static final String Service = "DNS";
    private static final String Version = "2018-08-01";
    private static final String Region = "cn-north-1";
    private static final String Host = "dns.volcengineapi.com";

    // 第二步:准备辅助函数。
    // sha256非对称加密
    public static byte[] hmacSHA256(byte[] key, String content) {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(key, "HmacSHA256"));
            return mac.doFinal(content.getBytes());
        } catch (Exception e) {
            return null;
        }
    }

    // sha256 hash算法
    public static String hashSHA256(byte[] content) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            return Hex.encodeHexString(md.digest(content));
        } catch (Exception e) {
            return null;
        }
    }

    private static String getAppointFormatDate(Date date) {
        DateFormat df = new SimpleDateFormat(TIME_FORMAT_V4);
        df.setTimeZone(tz);
        return df.format(date);
    }

    // 第三步:创建一个 API 请求函数。签名计算的过程包含在该函数中。
    public static byte[] request(String method, HashMap<String, String> query, HashMap<String, String> header, String ak, String sk, String action, byte[] body) throws URISyntaxException {

        // 第四步:创建身份证明。其中的 Service 和 Region 字段是固定的。ak 和 sk 分别代表 AccessKeyID 和
        // SecretAccessKey。
        // 同时需要初始化签名对象。一些签名计算时需要的属性也在这里处理。
        // 初始化身份证明
        HashMap<String, String> credential = new HashMap() {
            {
                put("accessKeyId", ak);
                put("secretKeyId", sk);
                put("service", Service);
                put("region", Region);
            }
        };
        ArrayList<NameValuePair> nvps = new ArrayList<>();
        for (Map.Entry<String, String> entry : query.entrySet()) {
            nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        nvps.add(new BasicNameValuePair("Action", action));
        nvps.add(new BasicNameValuePair("Version", Version));
        Collections.sort(nvps, new Comparator<NameValuePair>() {
            @Override
            public int compare(NameValuePair o1, NameValuePair o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });

        // 初始化签名结构
        RequestParam requestParam = new RequestParam(body, method, new Date(), "/", Host, "application/json", nvps);
        URI uri = new URIBuilder().addParameters(requestParam.queryList).build();
        // 第五步:接下来开始计算签名
        // 初始化签名结果变量
        String xDate = getAppointFormatDate(new Date());
        String shortXDate = xDate.substring(0, 8);
        String xContentSha256 = hashSHA256(body);
        // 第六步:计算签名
        String[] headStr = {"content-type", "host", "x-content-sha256", "x-date"};
        String signedHeadersStr = String.join(";", headStr);
        String[] headStrSecond = {"content-type:" + requestParam.contentType, "host:" + requestParam.host, "x-content-sha256:" + xContentSha256, "x-date:" + xDate};
        String preRequestStr = String.join("\n", headStrSecond);
        String[] preCanonicalRequestStr = {requestParam.method, requestParam.path, uri.getRawQuery(), preRequestStr, "", signedHeadersStr, xContentSha256};
        String canonicalRequestStr = String.join("\n", preCanonicalRequestStr);
        String hashedCanonicalRequest = hashSHA256(canonicalRequestStr.getBytes());
        String[] credentialStr = {shortXDate, credential.get("region"), credential.get("service"), "request"};
        String credentialScope = String.join("/", credentialStr);

        String[] preStringToSign = {"HMAC-SHA256", xDate, credentialScope, hashedCanonicalRequest};
        String stringToSign = String.join("\n", preStringToSign);
        byte[] kDate = hmacSHA256(credential.get("secretKeyId").getBytes(), shortXDate);
        byte[] kRegion = hmacSHA256(kDate, credential.get("region"));
        byte[] kService = hmacSHA256(kRegion, credential.get("service"));
        byte[] kSigning = hmacSHA256(kService, "request");
        String signature = Hex.encodeHexString(hmacSHA256(kSigning, stringToSign));
        String authorization = String.format("HMAC-SHA256 Credential=%s, SignedHeaders=%s, Signature=%s", credential.get("accessKeyId") + "/" + credentialScope, signedHeadersStr, signature);
        // 第七步,在request中,创建一个 HTTP 请求实例。
        HttpUriRequest request;
        if("POST".equalsIgnoreCase(method)){
            HttpPost httpPost = new HttpPost("https://" + requestParam.host + requestParam.path + "?" + uri.getRawQuery());
            // 第八步:将 Signature 签名写入HTTP Header 中,并发送 HTTP 请求。
            // 设置经过签名的5个HTTP Header
            httpPost.setEntity(new ByteArrayEntity(body));
            for (Map.Entry<String, String> entry : header.entrySet()) {
                httpPost.setHeader(entry.getKey(), entry.getValue());
            }
            request = httpPost;
        } else if("GET".equalsIgnoreCase(method)){
            HttpGet httpGet = new HttpGet("https://" + requestParam.host + requestParam.path + "?" + uri.getRawQuery());
            for (Map.Entry<String, String> entry : header.entrySet()) {
                httpGet.setHeader(entry.getKey(), entry.getValue());
            }
            request = httpGet;
        } else {
            throw new UnsupportedOperationException();
        }
        request.setHeader("Host", requestParam.host);
        request.setHeader("Content-Type", requestParam.contentType);
        request.setHeader("X-Date", xDate);
        request.setHeader("X-Content-Sha256", xContentSha256);
        request.setHeader("Authorization", authorization);

        CloseableHttpClient httpClient = HttpClients.createDefault();
        byte[] responseBody = null;

        // 发送 HTTP 请求。
        try {
            CloseableHttpResponse response = httpClient.execute(request);
            HttpEntity entity = response.getEntity();
            responseBody = EntityUtils.toByteArray(entity);
            EntityUtils.consume(entity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return responseBody;
    }

    public static void main(String[] args) throws URISyntaxException {
        //(POST 请求)调用 UpdateZone API
        HashMap<String, Object> requestBody = new HashMap<>();
        requestBody.put("ZID", 100);
        requestBody.put("Remark", "example");
        byte[] updateZoneResult = request("POST", new HashMap<>(), new HashMap<>(), AK, SK, "UpdateZone", JSON.toJSONBytes(requestBody));
        // 打印输出的结果
        System.out.println("response body:");
        if (updateZoneResult != null) {
            System.out.println(new String(updateZoneResult, StandardCharsets.UTF_8));
        } else {
            System.out.println("null");
        }

        // (GET 请求)调用 CheckZone API
        HashMap<String, String> query = new HashMap<>();
        query.put("ZoneName", "example.com");
        byte[] checkZoneResult = request("GET", query, new HashMap<>(), AK, SK, "CheckZone", new byte[]{});
        // 打印输出的结果
        System.out.println("response body:");
        if (checkZoneResult != null) {
            System.out.println(new String(checkZoneResult, StandardCharsets.UTF_8));
        } else {
            System.out.println("null");
        }
    }
}

Python 3 示例代码

下面的示例代码演示了如何基于 Python 3 调用 UpdateZone APICheckZone API 时对请求进行鉴权。

在运行示例代码之前,您需要 获取 Access Key ID 和 Secret Access Key。然后,您需要分别将 Access Key ID 和 Secret Access Key 的值传入示例代码中的 AK 变量和 SK 变量。另外,示例代码使用了 requests 库,您可以通过 python3 -m pip install requests 命令安装 requests 库。

import datetime
import hashlib
import hmac
import json
from urllib.parse import quote
from collections import OrderedDict

import requests

Service = "DNS"
Version = "2018-08-01"
Region = "cn-north-1"
Host = "dns.volcengineapi.com"
# 分别将 Access Key ID 和 Secret Access Key 的值传入 AK 变量和 SK 变量
AK = "ak"
SK = "sk"


def norm_query(params):
    query = ""
    for key in sorted(params.keys()):
        if type(params[key]) == list:
            for k in params[key]:
                query = (
                        query + quote(key, safe="-_.~") + "=" + quote(k, safe="-_.~") + "&"
                )
        else:
            query = (query + quote(key, safe="-_.~") + "=" + quote(params[key], safe="-_.~") + "&")
    query = query[:-1]
    return query.replace("+", "%20")


# 第一步:准备辅助函数。
# sha256 非对称加密
def hmac_sha256(key: bytes, content: str):
    return hmac.new(key, content.encode("utf-8"), hashlib.sha256).digest()


# sha256 hash算法
def hash_sha256(content: str):
    return hashlib.sha256(content.encode("utf-8")).hexdigest()


# 第二步:创建一个 API 请求函数。签名计算的过程包含在该函数中。
def request(method, query, header, ak, sk, action, body):
    # 第三步:创建身份证明。其中的 Service 和 Region 字段是固定的。ak 和 sk 分别代表
    # AccessKeyID 和 SecretAccessKey。同时需要初始化签名结构体。一些签名计算时需要的属性也在这里处理。
    # 初始化身份证明结构体
    credential = {
        "access_key_id": ak,
        "secret_access_key": sk,
        "service": Service,
        "region": Region,
    }
    # 初始化签名结构体
    query = {"Action": action, "Version": Version, **query}
    sorted_query = OrderedDict(sorted(query.items()))

    request_param = {
        "body":"",
        "host": Host,
        "path": "/",
        "method": method,
        "content_type": "application/json",
        "date": datetime.datetime.utcnow(),
        "query": sorted_query,
    }

    if method == "POST":
        request_param["body"] = json.dumps(body)

    # 第四步:接下来开始计算签名。在计算签名前,先准备好用于接收签算结果的 signResult 变量,并设置一些参数。
    # 初始化签名结果的结构体
    x_date = request_param["date"].strftime("%Y%m%dT%H%M%SZ")
    short_x_date = x_date[:8]
    x_content_sha256 = hash_sha256(request_param["body"])
    sign_result = {
        "Host": request_param["host"],
        "X-Content-Sha256": x_content_sha256,
        "X-Date": x_date,
        "Content-Type": request_param["content_type"],
    }
    # 第五步:计算 Signature 签名。
    signed_headers_str = ";".join(
        ["content-type", "host", "x-content-sha256", "x-date"]
    )
    canonical_request_str = "\n".join(
        [request_param["method"],
         request_param["path"],
         norm_query(request_param["query"]),
         "\n".join(
             [
                 "content-type:" + request_param["content_type"],
                 "host:" + request_param["host"],
                 "x-content-sha256:" + x_content_sha256,
                 "x-date:" + x_date,
             ]
         ),
         "",
         signed_headers_str,
         x_content_sha256,
         ]
    )
    hashed_canonical_request = hash_sha256(canonical_request_str)
    credential_scope = "/".join([short_x_date, credential["region"], credential["service"], "request"])
    string_to_sign = "\n".join(["HMAC-SHA256", x_date, credential_scope, hashed_canonical_request])
    k_date = hmac_sha256(credential["secret_access_key"].encode("utf-8"), short_x_date)
    k_region = hmac_sha256(k_date, credential["region"])
    k_service = hmac_sha256(k_region, credential["service"])
    k_signing = hmac_sha256(k_service, "request")
    signature = hmac_sha256(k_signing, string_to_sign).hex()
    sign_result["Authorization"] = "HMAC-SHA256 Credential={}, SignedHeaders={}, Signature={}".format(
        credential["access_key_id"] + "/" + credential_scope,
        signed_headers_str,
        signature,
    )
    header = {**header, **sign_result}
    # 第六步:将 Signature 签名写入 HTTP Header 中,并发送 HTTP 请求。
    if method == "POST":
        r = requests.post("https://{}{}".format(request_param["host"], request_param["path"]),
                          headers=header,
                          params=request_param["query"],
                          data=request_param["body"],
                          )
        return r.json()
    if method == "GET":
        r = requests.get("https://{}{}".format(request_param["host"], request_param["path"]),
                          headers=header,
                          params=request_param["query"],
                          data=request_param["body"],
                          )
        return r.json()


if __name__ == "__main__":
    # (POST 请求)调用 UpdateZone API
    request_body = {
        "ZID": 100,
        "Remark": "example",
    }
    update_zone_result = request("POST", {}, {}, AK, SK, "UpdateZone", request_body)
    print(update_zone_result)

    # (GET 请求)调用 CheckZone API
    request_query = {"ZoneName": "example.com"}
    check_zone_result = request("GET", request_query, {}, AK, SK, "CheckZone", {})
    print(check_zone_result)

请求鉴权算法

您可以使用以下任一方法提供鉴权信息。推荐您使用方法一。

(推荐)方法一:在请求头中包含鉴权信息

您需要在请求头中包含以下参数:

参数名称数据类型是否必选参数说明示例
X-Datestring表示签名计算的时间,以 UTC 表示。时间精度是秒。
20201103T104027Z

Authorization

string

该参数表示鉴权字符串。Authorization 的伪代码结构如下:

HMAC-SHA256 Credential = {AccessKey}/{ShortDate}/{Region}/{Service}/{Request}, SignedHeaders={SignedHeaders}, Signature={Signature}

Authorization 伪代码中的 Signature 参数表示签名。关于 Signature 参数的计算步骤,参见签名计算方式。关于 Authorization 伪代码中其他参数的说明,参见伪代码中参数的说明

该参数表示一个结构体。结构体中包含了 Signature

X-Security-Tokenstring如果您使用火山引擎账号的 Access Key ID 和 Secret Access Key 来计算 Authorization,则无需指定该参数。如果您使用的 Access Key ID 和 Secret Access Key 是安全令牌服务(STS)提供的,则需要指定该参数。该参数值就是 STS 颁发的临时安全凭证中的 SessionToken。参见 获取临时安全令牌STSeyJBY2NvdW50SW

方法二:在查询字符串中包含鉴权信息

您需要在查询字符串中包含以下查询参数。

参数名称数据类型是否必选参数说明示例
X-Datestring签名计算的时间,以 UTC 表示。时间精度是秒。
20201103T104027Z
X-Algorithmstring签名计算所使用的算法。该参数的值是 HMAC-SHA256HMAC-SHA256

X-Credential

string

X-Credential 的伪代码结构如下:

{AccessKey}/{ShortDate}/{Region}/{Service}/{Request}

关于 X-Credential伪代码中参数的说明,参见伪代码中参数的说明

AKLTMjI2ODVlYzI3ZGY1NGU4ZjhjYWRjMTlmNTM5OTZkYzE/20210913/cn-north-1/DNS/request

X-SignedHeaders

string

参与签名计算的请求头参数。多个请求头参数使用分号(;)分隔。这些请求头参数是根据参数名称升序排序的。X-SignedHeadersSignedHeaders 参数的定义是相同的。在您计算 CanonicalRequest 的参数值的时候需要使用 X-SignedHeaders

一般来说,X-SignedHeaders 的值是 host;x-content-sha256;x-date。您也可以指定任意请求头参数作为 X-SignedHeaders 的值。

host;x-content-sha256;x-date

X-Signaturestring一个经过计算得到的签名。关于签名的计算步骤,参见签名计算方式

签名计算方式

本章节主要介绍签名是如何计算的。

  • 本章节的伪代码中的 HMAC 方法使用的是 HMAC-SHA256 算法。
  • 本章节的伪代码中的 HexEncode 方法将字符串转换为十六进制编码格式的字符串。

Signature 是基于 kSigningStringToSign 参数计算而来的。Signature 的伪代码如下:

Signature = HexEncode(HMAC(kSigning, StringToSign))

kSigning

kSigning 表示用来计算签名的密钥。要计算 kSigning,您必须先获取您账号的 Access Key Secret,然后使用以下伪代码生成 kSigning

kSecret = <Your Access Key Secret>
kDate = HMAC(kSecret, ShortDate)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigning = HMAC(kService, "request")

关于 kSigning 伪代码中参数的说明,参见伪代码中参数的说明

StringToSign

StringToSign 表示用来计算签名的签名字符串。StringToSign 的伪代码如下:

// Hash 函数使用 SHA256 算法
StringToSign = Algorithm + '\n' + RequestDate + '\n' + CredentialScope + '\n' + HexEncode(Hash(CanonicalRequest))

关于 StringToSign 伪代码中 AlgorithmRequestDate 参数的说明,参见伪代码中参数的说明。StringToSign 伪代码中其他参数的说明如下。

CredentialScope

CredentialScope 表示凭证范围。CredentialScope 的伪代码如下:

{ShortDate}/{Region}/{Service}/{Request}

关于 CredentialScope 伪代码中参数的说明,参见伪代码中参数的说明

CanonicalRequest

CanonicalRequest 表示规范的请求。CanonicalRequest 的伪代码如下:

HTTPRequestMethod + '\n' + CanonicalURI + '\n' + CanonicalQueryString + '\n' + CanonicalHeaders + '\n' + SignedHeaders + '\n' + HexEncode(Hash(RequestPayload))

CanonicalRequest 伪代码中参数的说明如下:

  • HTTPRequestMethod:请求方法。
  • CanonicalURI:请求的 URI。
  • CanonicalQueryString:规范的查询字符串。CanonicalQueryString 的值是通过以下规则生成的:
    • 按参数名称对查询参数进行升序排序。
  • CanonicalHeaders:规范的请求头。CanonicalHeaders 是通过以下步骤生成的:
    • 将参与签名计算的请求头参数的名称转化成小写字母。
    • 在字符级别对这些名称进行升序排序。
    • 以 key-value 的格式拼接这些请求头参数。key 是请求头参数的名称,value 是请求头参数的值。
    • 在每个请求头参数后添加换行符(\n)。
  • SignedHeaders:参见伪代码中参数的说明
  • HexEncode(Hash(RequestPayload)):一个计算值。该值是通过对请求正文中 payload 的值应用 SHA256 哈希算法计算得到的。

伪代码中参数的说明

以下表格包含了本文中多个伪代码中参数的说明。

参数名称数据类型参数说明示例
AccessKeystring您账号的 Access Key ID。参考获取 Access KeyAKLTMjI2ODVlYzI3ZGY1NGU4ZjhjYWRjMTlmNTM5OTZkYzE
RequestDatestring该参数与 X-Date 的定义相同。20210913T081805Z
ShortDatestring该参数与 RequestDate 的定义相同,只不过时间精度是日。20210913
Regionstring云解析 DNS 服务所在的地域。该参数的取值是 cn-north-1cn-north-1
Servicestring云解析 DNS 的服务名称。该参数的取值是 DNSDNS
SignedHeadersstring参与签名计算的请求头参数。多个请求头参数使用分号(;)分隔。这些请求头参数是根据参数名称升序排序的。

一般来说,SignedHeaders 的值是 host;x-content-sha256;x-date。您也可以指定任意请求头参数作为 SignedHeaders 的值。
host;x-content-sha256;x-date
Algorithmstring签名计算所使用的算法。该参数的取值为 HMAC-SHA256HMAC-SHA256
Requeststring该参数是一个常量,值是 requestrequest

请求示例

GET https://dns.volcengineapi.com/?Action=ListZones&Version=2018-08-01

X-Date: 20230116T073702Z
Authorization: HMAC-SHA256 Credential=AKLTMjYxYTZmYWU4ZWYzNGI2NDg8NTUxODE1ZGVhNmIxZmQ/20230116/cn-north-1/DNS/request, SignedHeaders=x-content-sha256;x-date, Signature=5a394ce80456c7cdf989c28bd638807c8ead386eb15dd36e39952f405380aef2
ServiceName: DNS
最近更新时间:2025.06.23 20:22:15
这个页面对您有帮助吗?
有用
有用
无用
无用