您通过 HTTP 请求来调用火山引擎云解析(DNS)的 API。
在发送 HTTP 请求前,您需要理解以下内容:
API 请求的结构包含以下内容:
云解析 DNS 的 API 服务域名是 open.volcengineapi.com
。
您可以使用 HTTP
协议或 HTTPS
协议发送请求。推荐您使用 HTTPS
协议,其安全性更高。
关于 API 所使用的方法,参见每个 API 的说明。对于 POST 请求,您必须在请求头中指定 Content-Type: application/json
。
请求参数包括公共参数和每个 API 所特有的参数。
公共参数是每个 API 请求必须包含的参数。如果一个 API 请求缺失公共参数,请求会失败。以下表格中的公共参数必须包含在查询字符串(query string)中。
参数名称 | 数据类型 | 是否必选 | 说明 | 示例 |
---|---|---|---|---|
Action | String | 是 | API 名称。格式为 [a-zA-Z]+ 。 | CreateZone |
Version | String | 是 | API 版本。该参数的取值是 2018-08-01 。 | 2018-08-01 |
X-Expires | Integer | 否 | 签名的有效时间,单位为秒。默认值为 900。 | 900 |
每个请求中必须包含鉴权信息。该鉴权信息用以验证请求者的身份。
下面的示例代码演示了如何基于 Golang 调用 UpdateZone API 和 CheckZone 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 = "open.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 调用 UpdateZone API 和 CheckZone 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 = "open.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 调用 UpdateZone API 和 CheckZone 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 = "open.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-Date | string | 是 | 表示签名计算的时间,以 UTC 表示。时间精度是秒。 | 20201103T104027Z |
Authorization | string | 是 | 该参数表示鉴权字符串。
| 该参数表示一个结构体。结构体中包含了 |
X-Security-Token | string | 否 | 如果您使用火山引擎账号的 Access Key ID 和 Secret Access Key 来计算 Authorization,则无需指定该参数。如果您使用的 Access Key ID 和 Secret Access Key 是安全令牌服务(STS)提供的,则需要指定该参数。该参数值就是 STS 颁发的临时安全凭证中的 SessionToken。参见 获取临时安全令牌。 | STSeyJBY2NvdW50SW |
您需要在查询字符串中包含以下查询参数。
参数名称 | 数据类型 | 是否必选 | 参数说明 | 示例 |
---|---|---|---|---|
X-Date | string | 是 | 签名计算的时间,以 UTC 表示。时间精度是秒。 | 20201103T104027Z |
X-Algorithm | string | 是 | 签名计算所使用的算法。该参数的值是 HMAC-SHA256 。 | HMAC-SHA256 |
X-Credential | string | 是 | X-Credential 的伪代码结构如下:
关于 |
|
X-SignedHeaders | string | 是 | 参与签名计算的请求头参数。多个请求头参数使用分号(;)分隔。这些请求头参数是根据参数名称升序排序的。 |
|
X-Signature | string | 是 | 一个经过计算得到的签名。关于签名的计算步骤,参见签名计算方式。 |
本章节主要介绍签名是如何计算的。
HMAC
方法使用的是 HMAC-SHA256 算法。HexEncode
方法将字符串转换为十六进制编码格式的字符串。Signature
是基于 kSigning
和 StringToSign
参数计算而来的。Signature
的伪代码如下:
Signature = HexEncode(HMAC(kSigning, StringToSign))
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
的伪代码如下:
// Hash 函数使用 SHA256 算法 StringToSign = Algorithm + '\n' + RequestDate + '\n' + CredentialScope + '\n' + HexEncode(Hash(CanonicalRequest))
关于 StringToSign
伪代码中 Algorithm
和 RequestDate
参数的说明,参见伪代码中参数的说明。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
是通过以下步骤生成的:
\n
)。SignedHeaders
:参见伪代码中参数的说明。HexEncode(Hash(RequestPayload))
:一个计算值。该值是通过对请求正文中 payload
的值应用 SHA256 哈希算法计算得到的。以下表格包含了本文中多个伪代码中参数的说明。
参数名称 | 数据类型 | 参数说明 | 示例 |
---|---|---|---|
AccessKey | string | 您账号的 Access Key ID。参考获取 Access Key。 | AKLTMjI2ODVlYzI3ZGY1NGU4ZjhjYWRjMTlmNTM5OTZkYzE |
RequestDate | string | 该参数与 X-Date 的定义相同。 | 20210913T081805Z |
ShortDate | string | 该参数与 RequestDate 的定义相同,只不过时间精度是日。 | 20210913 |
Region | string | 云解析 DNS 服务所在的地域。该参数的取值是 cn-north-1 。 | cn-north-1 |
Service | string | 云解析 DNS 的服务名称。该参数的取值是 DNS 。 | DNS |
SignedHeaders | string | 参与签名计算的请求头参数。多个请求头参数使用分号(;)分隔。这些请求头参数是根据参数名称升序排序的。 一般来说, SignedHeaders 的值是 host;x-content-sha256;x-date 。您也可以指定任意请求头参数作为 SignedHeaders 的值。 | host;x-content-sha256;x-date |
Algorithm | string | 签名计算所使用的算法。该参数的取值为 HMAC-SHA256 。 | HMAC-SHA256 |
Request | string | 该参数是一个常量,值是 request 。 | request |
GET https://open.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