阿里云 API 签名机制的 Python 实现
在调用阿里云 API 的时候,最让人头疼的就是 API 的签名(Signature)机制,阿里云在通用文档中也有专项说明,但是仅仅有基于 Java 的实现代码示例。所以这里基于 Python 来分析下。
基本步骤
理论部分的详细内容参考阿里云官方帮助文档吧
具体 Python 实现
API 请求原理
简单来说调用阿里云 API 就是一个 http 请求(大多数为 GET, 这里也是基于 GET 请求),只是后面要跟一堆参数,例如一个查看快照的请求为:
http://ecs.aliyuncs.com/?SignatureVersion=1.0&Format=JSON&Timestamp=2017-08-07T05%3A50%3A57Z&RegionId=cn-hongkong&AccessKeyId=xxxxxxxxx&SignatureMethod=HMAC-SHA1&Version=2014-05-26&Signature=%2FeGgFfxxxxxtZ2w1FLt8%3D&Action=DescribeSnapshots&SignatureNonce=b5046ef2-7b2b-11e7-a3c5-00163e001831&ZoneId=cn-hongkong-b请求中所需要的公共参数(就是调用 API 都需要用到的参数)为:
SignatureVersion # 签名算法版本,目前为 1.0 Format # 返回消息的格式化方式,JSON or XML 默认值为 XML Timestamp # 请求的时间戳,UTC时间,例如: 2013-01-10T12:00:00Z AccessKeyId # 账号密钥 ID SignatureMethod # 签名方式,目前为 HMAC-SHA1 Version # 版本号,为日期形式,例如: 2014-05-26 每个产品不同 Signature # 最难搞定的签名 SignatureNonce # 唯一随机数,防止网络攻击。不同请求间使用不同的随机数。除了 Signature 之外,其它的参数都比较容易获得,有些甚至是固定的值,具体可以参考阿里云文档
除了公共参数之外,还需要具体接口(Action)的请求参数,每个 Action 接口的参数可以参考对应产品的接口文档,例如 DescribeLoadBalancers
而 Signature 是基于公共参数和接口参数的,所以比较复杂。
Signature 具体代码实现
构造规范化的请求字符串 (Canonicalized Query String)
- 构造 dict
Python 中体现参数一一对应的就是 dict, 创建一个 dict, 把请求参数些进去,这里简化参数只有这些:
- 排序
由于签名要求唯一性,包括顺序,所以需要按照参数名称排序
- URL 编码
由于在标准请求字符串中需要使用 UTF-8 字符集,对请求参数名称和值中有些不符合规范的字符要进行 url 编码,具体规则为:
字符 AZ、az、0~9 以及字符“-”、“_”、“.”、“~”不编码;
其它字符编码成 %XY 的格式,其中 XY 是字符对应 ASCII 码的 16 进制表示。比如英文的双引号(”)对应的编码为 %22;
对于扩展的 UTF-8 字符,编码成 %XY%ZA… 的格式;
英文空格( )要编码成 %20,而不是加号(+)。
注意:一般支持URL编码的库(比如 Java 中的 java.net.URLEncoder)都是按照 “application/x-www-form-urlencoded”的 MIME 类型的规则进行编码的。实现时可以直接使用这类方式进行编码,把编码后的字符串中加号(+)替换成 %20、星号(*)替换成 %2A、%7E 替换回波浪号(~),即可得到上述规则描述的编码字符串。
这里使用 python 中的 urllib 库来进行编码:
- 生成标准化请求字符串
构造被签名字符串 StringToSign
规则为:
StringToSign=
HTTPMethod + “&” +
percentEncode(“/”) + ”&” +
percentEncode(CanonicalizedQueryString)
所以在这个实例中
计算 HMAC 值
计算签名值
到此生成了 signature 签名
添加签名
所以在这个实例中,最终请求的 url 为
拿到浏览器直接访问即可,得到结果为:
{"Message":"The input parameter \"Action\" that is mandatory for processing this request is not supplied.","RequestId":"129880D4-710D-4D2C-9F8B-12777FA1D3C6","HostId":"ecs.aliyuncs.com","Code":"MissingParameter"}由于是测试环境,就给了三个参数,所以还少很多参数,正常来说把这些参数都加上,然后生成 signature,组成 url 后直接访问就可以得到结果。
文档 来自:https://www.jianshu.com/p/7574349a5042
转载于:https://www.cnblogs.com/Qing-840/p/9300514.html
总结
以上是生活随笔为你收集整理的阿里云 API 签名机制的 Python 实现的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 我我我
- 下一篇: Python | 四种运行其他程序的黑科