您通过 HTTP 请求来调用火山引擎移动解析(HTTPDNS)的 API。
在发送 HTTP 请求前,您需要理解以下内容:
API 请求的结构包含以下内容:
移动解析 HTTPDNS 的服务地址是 open.volcengineapi.com
。
您可以使用 HTTP
协议或 HTTPS
协议发送请求。推荐您使用 HTTPS
协议,其安全性更高。
关于 API 所使用的方法,参见每个 API 的说明。对于 POST 请求,您必须在请求头中指定 Content-Type: application/json
。
请求参数包括公共参数和每个 API 所特有的参数。
公共参数是每个 API 请求必须包含的参数。如果一个 API 请求缺失公共参数,请求会失败。以下表格中的公共参数必须包含在查询字符串(query string)中。
参数名称 | 数据类型 | 是否必选 | 说明 | 示例 |
---|---|---|---|---|
Action | String | 是 | API 名称。格式为 [a-zA-Z]+ 。 | CreateHTTPDNS |
Version | String | 是 | API 版本。该参数的取值是 2023-09-01 。 | 2023-09-01 |
X-Expires | Integer | 否 | 签名的有效时间,单位为秒。默认值为 900。 | 900 |
每个请求中必须包含鉴权信息。该鉴权信息用以验证请求者的身份。
下面的示例代码演示了如何基于 Golang 调用 时对请求进行鉴权。
在运行示例代码之前,您需要 获取 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 = "2023-09-01" const Service = "httpdns" 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, }, } // 第三步:创建一个 HttpDNS 的 API 请求函数。签名计算的过程包含在该函数中。 func requestHttpDNS(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 AddDomainParam struct { Domain string `json:"Domain"` } func main() { // (POST 请求)调用 AddDomain API bodyParam := AddDomainParam{ Domain: "www.example1.com", } 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" addDomainResult, err := requestHttpDNS("POST", map[string][]string{}, map[string]string{}, AccessKey, SecretAccessKey, "AddDomain", body) if err != nil { fmt.Printf("do request failed: %v", err) return } // 打印输出的结果 fmt.Println(string(addDomainResult)) // (GET 请求)调用 AddDomain API QueryParam := map[string][]string{"Domain": []string{"www.example2.com"}} addDomainResult2, err := requestHttpDNS("GET", QueryParam, map[string]string{}, AccessKey, SecretAccessKey, "AddDomain", []byte{}) if err != nil { fmt.Printf("do request failed: %v", err) return } // 打印输出的结果 fmt.Println(string(addDomainResult2)) }
您可以使用以下任一方法提供鉴权信息。推荐您使用方法一。
您需要在请求头中包含以下参数:
参数名称 | 数据类型 | 是否必选 | 参数说明 | 示例 |
---|---|---|---|---|
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 | 移动解析 HTTPDNS 服务所在的地域。该参数的取值是 cn-north-1 。 | cn-north-1 |
Service | string | 移动解析 HTTPDNS 的服务名称。该参数的取值是 httpdns 。 | httpdns |
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=GetHttpDnsStatus&Version=2023-09-01 X-Date: 20231016T073702Z Authorization: HMAC-SHA256 Credential=AKLTMjYxYTZmYWU4ZWYzNGI2NDg8NTUxODE1ZGVhNmIxZmQ/20231016/cn-north-1/httpdns/request, SignedHeaders=x-content-sha256;x-date, Signature=5a394ce80456c7cdf989c28bd638807c8ead386eb15dd36e39952f405380aef2 ServiceName: httpdns