本文介紹了阿里雲 OpenAPI 的 RPC 風格介面,涵蓋請求的組成部分、如何構造 OpenAPI 請求、擷取返回結果的方法以及簽名機制等。阿里雲 RPC OpenAPI 向開發人員提供 HTTP 介面,方便自研阿里雲 RPC 調用風格的 OpenAPI SDK。
不再推薦使用該訪問方式,請移步參考V3版本請求體&簽名機制。
RPC 風格簡介
RPC(Remote Procedure Call)是一種允許用戶端以類似本地函數調用方式遠程調用服務端方法的協議。阿里雲的 RPC 介面主要支援以下兩種 HTTP 方法:
GET:用於從伺服器擷取資源。
POST:用於向伺服器提交資料或請求操作。
HTTP 要求結構
一個完整的阿里雲 RPC 請求由以下部分組成:
名稱 | 是否必選 | 描述 | 樣本值 |
協議 | 是 | 支援通過 | https:// |
服務地址 | 是 | 即 Endpoint。您可以查閱不同雲產品的服務接入地址文檔,在OpenAPI中的服務地區可尋找。 | ecs.aliyuncs.com |
公用請求參數 | 是 | 阿里雲 OpenAPI 的公用請求參數,更多資訊,請參見下文公用請求參數。 | Action |
介面自訂請求參數 | 否 | 每個 OpenAPI 自訂的請求參數,建議您在阿里雲 OpenAPI 開發人員門戶進行試用。 | RegionId |
HTTPMethod | 是 | RPC 請求 Method 支援 POST 或者 GET。 | GET |
公用請求參數
每個 RPC 請求都需包含以下關鍵參數:
名稱 | 類型 | 是否必選 | 描述 | 樣本值 |
Action | String | 是 | API 的名稱。您可以訪問阿里雲 OpenAPI 開發人員門戶,搜尋您想調用的 OpenAPI 。 | CreateInstance |
Version | String | 是 | API 版本。您可以訪問阿里雲 OpenAPI 開發人員門戶,查看您調用 OpenAPI 對應的 API 版本。例如簡訊服務產品,您可以通過查看雲產品首頁中看到API 版本為 2017-05-25。 | 2014-05-26 |
Format | String | 否 | 指定返回資料格式,可選 JSON 或 XML,預設為 XML。 | JSON |
AccessKeyId | String | 是 | 阿里雲存取金鑰 ID。您可以在RAM 控制台查看您的 AccessKeyId。如需建立 AccessKey,請參見建立AccessKey。 | yourAccessKeyId |
SignatureNonce | String | 是 | 簽名唯一隨機數。用於防止網路重放攻擊,建議您每一次請求都使用不同的隨機數,隨機數位元無限制。 | 15215528852396 |
Timestamp | String | 是 | 目前時間戳,有效期間為31分鐘,即產生時間戳記後需要在31分鐘內發起請求。按照時間格式ISO8681標準表示,並需要使用 UTC時間,格式為 樣本: | 2018-01-01T12:00:00Z |
SignatureMethod | String | 是 | 簽名方式。目前為固定值 | HMAC-SHA1 |
SignatureVersion | String | 是 | 簽名演算法版本。目前為固定值 | 1.0 |
Signature | String | 是 | 請求籤名,使用者請求的身分識別驗證。更多資訊,請參見後文簽名機制。 | Pc5WB8gokVn0xfeu%2FZV%2BiNM1dgI%3D |
介面請求構造
步驟一:構造介面 URL
介面 URL 由以下部分組成:
[協議][服務地址]?[公用參數][業務請求參數]
。POST 方法應將業務參數放於請求體中,GET 方法的參數則在 URL 查詢字串中。
對請求參數進行正常化編碼。例如: Timestamp 的參數值為 2016-02-23T12:46:24Z ,編碼後為 2016-02-23T12%3A46%3A24Z 。編碼方式請參見參數編碼方式。
介面 URL 樣本:
http://ecs.aliyuncs.com/?SignatureVersion=1.0&Action=DescribeDedicatedHosts&Format=XML&SignatureNonce=3ee8c1b8-xxxx-xxxx-xxxx-xxxxxxxxx&Version=2014-05-26&AccessKeyId=testid&Signature=OLeaidS1JvxuMvnyHOwuJ%2BuX5qY%3D&SignatureMethod=HMAC-SHA1&Timestamp=2016-02-23T12%3A46%3A24Z&RegionId=cn-hangzhou&Status=Available
步驟二:發起介面調用
GET 方法可使用瀏覽器、curl 或者 wget 等工具發起請求。
POST方法需在請求體中傳入業務請求參數,並佈建要求頭的
Content-Type
為application/x-www-form-urlencoded
。
介面返回結果
返回結果主要有 XML 和 JSON 兩種格式,預設為 XML ,可通過公用請求參數Format
指定返回結果的格式。
為了便於您查看,API 文檔返回樣本均進行了換行和縮排等處理,實際返回結果無換行和縮排處理。
當介面調用成功時,將返回請求 ID,HTTP 狀態代碼為 2xx(不顯示在響應本文中)。成功響應樣本如下:
XML :
<?xml version="1.0" encoding="UTF-8"?> <!--結果的根結點-->
<ActionResponse> <!--返回請求標籤-->
<RequestId>4C467B38-3910-447D-87BC-AC049166F216</RequestId> <!--返回結果資料-->
</ActionResponse>
JSON :
{
"RequestId": "4C467B38-3910-447D-87BC-AC049166F216" /* 返回結果資料 */
}
介面調用出錯時,返回請求 ID、服務節點、錯誤碼和錯誤資訊,HTTP 狀態代碼為 4xx 或 5xx。錯誤響應樣本如下:
XML :
<?xml version="1.0" encoding="UTF-8"?><!--結果的根結點-->
<Error>
<RequestId>540CFF28-407A-40B5-B6A5-74Bxxxxxxxxx</RequestId> <!--請求 ID-->
<HostId>ecs.aliyuncs.com</HostId> <!--服務節點-->
<Code>MissingParameter.CommandId</Code> <!--錯誤碼-->
<Message>The input parameter “CommandId” that is mandatory for processing this request is not supplied.</Message> <!--錯誤資訊-->
</Error>
JSON :
{
"RequestId": "540CFF28-407A-40B5-B6A5-74Bxxxxxxxxx", /* 請求 ID */
"HostId": "ecs.aliyuncs.com", /* 服務節點 */
"Code": "MissingParameter.CommandId", /* 錯誤碼 */
"Message": "The input parameter “CommandId” that is mandatory for processing this request is not supplied." /* 錯誤資訊 */
}
介面調用出錯後,您可以根據返回的 RequestId,在阿里雲OpenAPI開發人員門戶-診斷中排查。此外,您還可以查閱公用錯誤碼以及API 錯誤中心。當您無法排查錯誤時,可以提交工單,並在工單中註明服務節點 HostId 和 RequestId。
簽名機制
為了確保 API 的安全性,每個請求都需通過簽名(Signature)進行身分識別驗證。以下是簽名計算的步驟:
步驟一:構造正常化請求字串
1、參數排序:按照參數首字母的字典順序對參數排序,排序參數包括公用請求參數和介面自訂參數(即 OpenAPI 文檔中的請求參數),不包括公用請求參數中的Signature
參數。 公用請求參數詳情,請參見上文公用請求參數。虛擬碼如下:
// 例:參數名集合 {b, a, C} 排序後為 {C, a, b}
sortParams = sorted(params.keys())
2、編碼參數:使用 UTF-8 字元集按照RFC3986規則編碼請求參數和參數取值,編碼具體規則請參看參數編碼方式。為方便表述,我們將此步驟的編碼方法,命名為 encodeURIComponent
。虛擬碼如下:
// 例:請求參數為測試,參數取值為中文 編碼後分別是%E6%B5%8B%E8%AF%95和%E4%B8%AD%E6%96%87
encodeURIComponent(sortParams.keys, sortParams.values)
3、串連參數:使用等號(=)串連第二步得到的編碼後請求參數和參數值。然後用&
串連所有參數。注意參數排序與第1步一致。虛擬碼如下:
// 例:編碼後請求參數為test,參數取值為testvalue,則拼接為test=testvalue
encodeURIComponentParam.key=encodeURIComponentParam.value
得到了正常化請求字串CanonicalizedQueryString
。
步驟二:建構簽章字串
1、構造待簽名字串 stringToSign
。該字串構造規則的虛擬碼如下:
String stringToSign =
HTTPMethod + "&" + // HTTPMethod:發送請求的 HTTP 方法,例如 GET。
encodeURIComponent("/") + "&" + // encodeURIComponent 為步驟一第2步的編碼方法
encodeURIComponent(CanonicalizedQueryString) // CanonicalizedQueryString 為步驟一擷取的正常化請求字串。
2、計算簽名。按照RFC2104的定義,通過您傳入的 AccessKeyId 對應的密鑰 AccessSecret,使用 HMAC-SHA1
的簽名演算法,計算待簽名字串StringToSign
的簽名。其中 Base64() 為編碼計算函數,HMAC_SHA1() 為 HMAC_SHA1 簽名函數,傳回值為 HMAC_SHA1 加密後原始位元組,而非16進位字串,UTF_8_Encoding_Of() 是 UTF-8 字元編碼函數,虛擬碼如下:
String signature = Base64(HMAC_SHA1(AccessSecret + "&", UTF_8_Encoding_Of(stringToSign)))
使用 HMAC-SHA1 簽名演算法,計算得到的公用參數 Signature 的簽名值 signature
。
簽名樣本
本樣本以調用 ECS DescribeDedicatedHosts查詢一台或多台Dedicated Host的詳細資料為例。假設 AccessKeyID 為 testid, AccessKeySecret 為 testsecret,SignatureNonce 為 edb2b34af0af9a6d14deaf7c1a5315eb, Timestamp 為 2023-03-13T08:34:30Z,簽名流程如下:
構造正常化請求字串。
http://ecs.aliyuncs.com/?AccessKeyId=testid&Action=DescribeDedicatedHosts&Format=JSON&RegionId=cn-beijing&SignatureMethod=HMAC-SHA1&SignatureNonce=edb2b34af0af9a6d14deaf7c1a5315eb&SignatureVersion=1.0&Tag.1.Key=testkey&Tag.1.Value=testvalue&Timestamp=2023-03-13T08%3A34%3A30Z&Version=2014-05-26
構造待簽名字串
stringToSign
。GET&%2F&AccessKeyId%3Dtestid%26Action%3DDescribeDedicatedHosts%26Format%3DJSON%26RegionId%3Dcn-beijing%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3Dedb2b34af0af9a6d14deaf7c1a5315eb%26SignatureVersion%3D1.0%26Tag.1.Key%3Dtestkey%26Tag.1.Value%3Dtestvalue%26Timestamp%3D2023-03-13T08%253A34%253A30Z%26Version%3D2014-05-26
計算簽名值。例如
AccessKeySecret=testsecret
,用於計算的 Key 為testsecret&
(注意:加上尾碼&)。計算得到的簽名值為fRmq1o6saIIjVlawOy+o6jDU9JQ=
。虛擬碼如下:String Signature = Base64(HMAC_SHA1(AccessSecret + "&",UTF_8_Encoding_Of(stringToSign)))
得到完整的URL。添加RFC3986規則編碼後的
Signature=fRmq1o6saIIjVlawOy%2Bo6jDU9JQ%3D
到第1步的 URL 中。https://ecs.cn-beijing.aliyuncs.com/?AccessKeyId=testid&Action=DescribeDedicatedHosts&Format=JSON&RegionId=cn-beijing&SignatureMethod=HMAC-SHA1&SignatureNonce=edb2b34af0af9a6d14deaf7c1a5315eb&SignatureVersion=1.0&Tag.1.Key=testkey&Tag.1.Value=testvalue&Timestamp=2023-03-13T08%3A34%3A30Z&Version=2014-05-26&Signature=fRmq1o6saIIjVlawOy%2Bo6jDU9JQ%3D
Version 欄位值和網域名稱是對應關係(服務網域名稱和 Version 值請參看對應雲產品 OpenAPI 雲產品首頁),錯誤的網域名稱或 Version 值可能導致 InvalidVersion
錯誤。
通過第4步得到的 URL,您可以使用瀏覽器、curl 或者 wget 等工具發起HTTP請求調用DescribeDedicatedHosts
,查詢一台或多台Dedicated Host的詳細資料。
附錄
參數編碼方式
在阿里雲 OpenAPI 呼叫中,請求參數和參數值需使用 UTF-8 字元集按照RFC3986規則進行編碼。具體編碼規則如下:
字元 A~Z、a~z、0~9 以及字元
-
、_
、.
、~
不編碼。對其他 ASCII 碼字元進行編碼。編碼格式為%加上16進位的 ASCII 碼。例如半形雙引號(
"
)將被編碼為%22
。非 ASCII 碼通過 UTF-8 編碼。
空格編碼成
%20
,不使用加號(+
)表示空格。