如何调用服务端API
在调用服务端API之前,您需要仔细阅读接入指南,拿到相关的ApiKey
之后,再使用特定的步骤计算接口调用签名,用于校验调用者的真实身份信息。
服务端API固定参数
服务端API,需要在传递以下固定header参数:
参数名 | 参数说明 |
---|---|
Content-Md5 | 当前请求体参数的MD5摘要 |
X-Ca-Api-Key | 参见【系统管理】-【API集成】-【API KEY】 |
X-Ca-Timestamp | 当前时间戳,秒级(与北京时间误差不可超过5分钟) |
X-Ca-Nonce | 随机字符串 |
X-Ca-Signature | 当前请求的签名字符串,计算方法详见:《签名计算方法》 |
签名计算方法
要计算当前请求的签名字符串(X-Ca-Signature
),在发起HTTP请求前,您需要准备以下相关参数
签名计算所需参数
参数名 | 示例值 | 说明 |
---|---|---|
Content-Md5 | 43ae24af5bb530225da6bd0a46508ba8 | 当前请求体参数的MD5摘要, 如:MD5({"method":"GET","path":"/device_info"}) |
X-Ca-Timestamp | 1708426191 | 当前时间戳,秒级(与北京时间误差不可超过5分钟) |
X-Ca-Nonce | c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44 | 生成的随机字符串 |
ApiSecret | NmJiN2Y2MWMtYjgyNy00M2IzLWI2YWUtZTQ1NGMyZGY2MjRj | 参见【系统管理】-【API集成】-【API KEY】 |
签名计算过程
1, 按上述表格所示,准备计算签名所需要的相关参数备用。
2, 将Content-Md5,X-Ca-Timestamp,X-Ca-Nonce按照指定格式拼接字符串
let stringToSign = Content-Md5 + "\n" + X-Ca-Timestamp + "\n" + X-Ca-Nonce + "\n"
3, 使用ApiSecret作为密钥,对拼接字符串进行HmacSHA256签名计算
let result = hmac.sha256(stringToSign, ApiSecret)
4,对HmacSHA256签名结果进行标准BASE64转码,得到最终签名结果
let signature = base64.StdEncoding.EncodeToString(result)
5, 以上步骤,可简单概括为
BASE64(HMAC_SHA256("$Content-Md5\n$X-Ca-Timestamp\n$X-Ca-Nonce\n", $ApiSecret))
注意事项
1,上述签名过程中出现的代码均为伪代码,实际实现时请以您使用的语言为准。
2,为了防止ApiSecret
泄漏,计算签名以及服务端API的调用过程应该在您的服务器上完成,不要在客户端进行计算。
示例代码
为方便理解,下列示例代码演示服务端API的调用过程(使用Go语言实现)请根据业务需要自行处理。
如需完整业务流程的示例代码,可参阅:参考/示例代码
const (
apiKey = "<yourApiKey>"
apiSecret = "<yourApiSecret>"
)
// createSignatureRequest 创建签名后的请求
func createSignatureRequest(method string, url string, body []byte) (*http.Request, error) {
// 准备签名所需参数
bodyHash := md5.Sum(body)
contentMd5 := hex.EncodeToString(bodyHash[:])
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
nonce := uuid.New().String()
// 计算请求签名
hash := hmac.New(sha256.New, []byte(apiSecret))
hash.Write([]byte(fmt.Sprintf("%s\n%s\n%s\n", contentMd5, timestamp, nonce)))
signature := base64.StdEncoding.EncodeToString(hash.Sum(nil))
// 构建请求
httpRequest, _ := http.NewRequest(method, url, strings.NewReader(string(body)))
// 传入相关参数到Header
httpRequest.Header.Add("Content-Md5", contentMd5)
httpRequest.Header.Add("X-Ca-Api-Key", apiKey)
httpRequest.Header.Add("X-Ca-Timestamp", timestamp)
httpRequest.Header.Add("X-Ca-Nonce", nonce)
httpRequest.Header.Add("X-Ca-Signature", signature)
return httpRequest, nil
}
func main() {
// 调用服务端API
authUrl := "https://openapi.sunlogin.oray.com/keyguard/authorization_code"
requestBody := "{\"method\":\"GET\",\"path\":\"/device_info\"}"
httpRequest, _ := createSignatureRequest(http.MethodPost, authUrl, []byte(requestBody))
httpResponse, err := http.DefaultClient.Do(httpRequest)
defer httpResponse.Body.Close()
if err != nil {
panic(errors.Wrap(err, "send request fail"))
}
responseBody, err := io.ReadAll(httpResponse.Body)
fmt.Printf("Response: %d, %s, Err: %v\n", httpResponse.StatusCode, responseBody, err)
}
修改于 25 天前