文档

V2版本RPC风格请求体&签名机制

更新时间:
一键部署

本文介绍了阿里云 OpenAPI 的 RPC风格接口,包括RPC OpenAPI 请求的组成部分,如何通过这些组成部分构造一个 OpenAPI 请求,如何获取返回结果以及签名机制等。阿里云 RPC OpenAPI 向开发者提供HTTP接口,如果您想要自研阿里云RPC调用风格的OpenAPI SDK,您可以参看本文,来构造 HTTP 请求调用对应的 OpenAPI 。

重要

不再推荐使用该访问方式,请移步参考V3版本请求体&签名机制

HTTP 请求结构

一个完整的阿里云 OpenAPI 请求,包含以下部分。

名称

是否必选

描述

示例值

协议

您可以查阅不同云产品的 API 参考文档进行配置。支持通过HTTPHTTPS协议进行请求通信。为了获得更高的安全性,推荐您使用HTTPS协议发送请求。取值范围为https://或者 http://

https://

服务地址

即 Endpoint。您可以查阅不同云产品的服务接入地址文档,查阅不同服务区域下的服务地址。

ecs.aliyuncs.com

公共请求参数

阿里云 OpenAPI 的公共请求参数,后文将详细说明。参见后文公共请求参数

Action

接口自定义请求参数

每个 OpenAPI 自定义的请求参数,建议您在阿里云 OpenAPI 开发者门户进行试用。

RegionId

HTTPMethod

RPC 请求 Method 支持 POST 或者 GET。

GET

公共请求参数

阿里云 OpenAPI 公共请求参数介绍如下:

名称

类型

是否必选

描述

示例值

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

***

SignatureNonce

String

签名唯一随机数。用于防止网络重放攻击,建议您每一次请求都使用不同的随机数,随机数位数无限制。

15215528852396

Timestamp

String

当前时间戳,有效期为31分钟,即生成时间戳后需要在31分钟内发起请求。按照时间格式标准表示,并需要使用 UTC时间,格式为yyyy-MM-ddTHH:mm:ssZ

示例:2018-01-01T12:00:00Z表示北京时间2018年01月01日20点00分00秒。

2018-01-01T12:00:00Z

SignatureMethod

String

签名方式。目前为固定值 HMAC-SHA1

HMAC-SHA1

SignatureVersion

String

签名算法版本。目前为固定值 1.0

1.0

Signature

String

请求签名,用户请求的身份验证。详细签名机制,请参见后文签名机制

Pc5WB8gokVn0xfeu%2FZV%2BiNM1dgI%3D

接口请求构造

步骤一:构造接口 URL

1、接口 URL 的组成部分为:[协议][服务地址]?[公共参数][业务请求参数]。其中 POST 方法的接口,为了避免 URL 过长,我们建议业务请求参数在 body 中传入。GET 方法的接口业务请求参数则在 query 中传入。

2、对请求参数进行规范化编码。编码方式请参看参数编码方式。例如 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

步骤二:发起接口调用

阿里云 OpenAPI RPC 接口,只有 GET 和 POST 两种 method。

对于 GET 方法的接口,您可以使用浏览器、curl 或者 wget 等工具,用步骤一的接口 URL 发送 HTTP请求。

对于 POST 方法的接口,我们建议业务请求参数在 body 中传入,其中请求头的 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 的安全使用,在调用 API 时阿里云会对每个 API 请求通过签名(Signature)进行身份验证。无论使用 HTTP 还是 HTTPS 协议提交请求,都需要在请求中包含签名信息。下文介绍计算签名的方法和示例。

步骤一:构造规范化请求字符串

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、使用等号(=)连接第二步得到的编码后请求参数和参数取值。伪代码如下:

// 例:编码后请求参数为test,参数取值为testvalue,则拼接为test=testvalue
encodeURIComponentParam.key=encodeURIComponentParam.value

4、使用与号(&)连接编码后的请求参数,注意参数排序与第1步一致。

5、现在,您得到了规范化请求字符串,为方便表述,我们将步骤一得到的字符串命名为 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)))

现在您得到了公共参数 Signature 的签名值 signature

签名示例

本示例以调用 ECS DescribeDedicatedHosts查询一台或多台专有宿主机的详细信息为例。假设您获得了 AccessKeyID 为 testid, AccessKeySecret 为 testsecret,SignatureNonce 为 edb2b34af0af9a6d14deaf7c1a5315eb, Timestamp 为 2023-03-13T08:34:30Z,签名流程如下:

  1. 构造规范化请求字符串。

    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
  2. 构造待签名字符串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
  3. 计算签名值。例如 AccessKeySecret=testsecret,用于计算的 Key 为testsecret&(注意:加上后缀&)。计算得到的签名值为fRmq1o6saIIjVlawOy+o6jDU9JQ=。伪代码如下:

    String Signature = Base64(HMAC_SHA1(AccessSecret + "&",UTF_8_Encoding_Of(stringToSign)))
  4. 添加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,查询一台或多台专有宿主机的详细信息。

附录

参数编码方式

在阿里云 OpenAPI 调用中,我们需要对请求参数和请求值,使用 UTF-8 字符集按照RFC3986规则进行编码。为方便表述,我们将此步骤的编码方法,命名为 encodeURIComponent,具体编码规则如下:

  • 字符 A~Z、a~z、0~9 以及字符-_.~不编码。

  • 对其他 ASCII 码字符进行编码。编码格式为%加上16进制的 ASCII 码。例如半角双引号(")将被编码为 %22

  • 非 ASCII 码通过 UTF-8 编码。

  • 空格编码成%20,而不是加号(+)。

相关文档

区分ROA风格和RPC风格

  • 本页导读 (1)
文档反馈