在调用阿里云 API 的时候,最让人头疼的就是 API 的签名(Signature)机制,阿里云在通用文档中也有专项说明,但是仅仅有基于 Java 的实现代码示例。所以这里基于 Python 来分析下。

基本步骤

  1. 构造规范化的请求字符串 (Canonicalized Query String)
  2. 构造被签名字符串 StringToSign
  3. 计算 HMAC 值
  4. 计算签名值
  5. 添加签名
    理论部分的详细内容参考阿里云官方帮助文档

具体 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, 把请求参数些进去,这里简化参数只有这些:
>>> D = {
'Format':'JSON',
'Version':'2014-05-26',
'SignatureMethod':'HMAC-SHA1'
}
  • 排序
    由于签名要求唯一性,包括顺序,所以需要按照参数名称排序
>>> sortedD = sorted(D.items(), key=lambda x: x[0])
>>> sortedD
[('Format', 'JSON'),
('SignatureMethod', 'HMAC-SHA1'),
('Version', '2014-05-26')] # 先通过 D.items() 转化为 List, 然后利用 sorted 方式按照 key 排序
  • 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 库来进行编码:

>>> def percentEncode(str):
res = urllib.quote(str.decode(sys.stdin.encoding).encode('utf8'), '')
res = res.replace('+', '%20')
res = res.replace('*', '%2A')
res = res.replace('%7E', '~')
return res
# 这里构造一个编码函数,对一个字符串进行编码,返回编码后的字符串
  • 生成标准化请求字符串
>>> canstring = ''
>>> for k,v in sortedD:
canstring += '&' + percentEncode(k) + '=' + percentEncode(v)
>>> canstring
'&Format=JSON&SignatureMethod=HMAC-SHA1&Version=2014-05-26'

构造被签名字符串 StringToSign

规则为:

StringToSign=
HTTPMethod + “&” +
percentEncode(“/”) + ”&” +
percentEncode(CanonicalizedQueryString)

所以在这个实例中

>>> stringToSign = 'GET&%2F&' + percentEncode(canstring[1:])
>>> stringToSign
'GET&%2F&Format%3DJSON%26SignatureMethod%3DHMAC-SHA1%26Version%3D2014-05-26'
# >>> percentEncode(“/”)
# %2F

计算 HMAC 值

>>> access_key_secret = 'access_key_secret'
>>> h = hmac.new(access_key_secret + "&", stringToSign, sha1)
>>> h
<hmac.HMAC instance at 0x35ed440>
# access_key_secret 是通过阿里云账号中的 AK 中获取的,和 access_key_id 对应,测试的时候使用的是 'access_key_secret'

计算签名值

>>> signature = base64.encodestring(h.digest()).strip()
>>> signature
'sq8LVH+ZItZiVQ0/rVnHV1kP/BE='

到此生成了 signature 签名

添加签名

>>> D['Signature'] = signature
>>> D
{'Format': 'JSON',
'Signature': 'sq8LVH+ZItZiVQ0/rVnHV1kP/BE=',
'SignatureMethod': 'HMAC-SHA1',
'Version': '2014-05-26'}

所以在这个实例中,最终请求的 url 为

>>> url = 'http://ecs.aliyuncs.com/?' + urllib.urlencode(D)
>>> url
'http://ecs.aliyuncs.com/?SignatureMethod=HMAC-SHA1&Version=2014-05-26&Signature=sq8LVH%2BZItZiVQ0%2FrVnHV1kP%2FBE%3D&Format=JSON'

拿到浏览器直接访问即可,得到结果为:

{"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

阿里云 API 签名机制的 Python 实现的更多相关文章

  1. 阿里云 API调用实践(python语言)

    1.结论:阿里云的SDK开发,其实就是远程调用API,python的代码就是一个外壳,核心是封装成一个http报文,利用json格式,进行RPC调用. 2.SDK调用API的套路如下: # -*- c ...

  2. 阿里云视频直播API签名机制源码

    阿里云视频直播API签名机制源码 本文展示:通过代码实现下阿里视频直播签名处理规则 阿里云视频直播签名机制,官方文档链接:https://help.aliyun.com/document_detail ...

  3. Python 调用阿里云 API 收集 ECS 数据

    #!/usr/bin/env python # coding: utf-8 # author: Wang XiaoQiang ''' 功能介绍: 1.调用阿里云API,收集所有区域 ECS 信息 2. ...

  4. 【阿里云API】 阿里云API调用的若干说明

    阿里云API 为了监控我们使用的一些阿里云产品,需要些一些脚本,定时调用这些脚本来获得相关阿里云产品的信息. ■ 概述 调用阿里云API大约分成两类方法,一个是直接从HTTP协议开始,自己根据阿里云的 ...

  5. 阿里云API网关(9)常见问题

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  6. 阿里云API网关!

    API 网关(API Gateway)提供高性能.高可用的 API 托管服务,帮助用户对外开放其部署在 ECS.容器服务等阿里云产品上的应用,提供完整的 API 发布.管理.维护生命周期管理.用户只需 ...

  7. 浅析阿里云API网关的产品架构和常见应用场景

    自上世纪60年代计算机网络发展开始,API(Application Programming Interface )随之诞生,API即应用程序接口,是实现系统间衔接的桥梁.时至今日,API市场已经形成了 ...

  8. 阿里云API网关(11)外网访问 阿里云API网关内定义的API步骤:

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  9. 阿里云物联网平台体验(树莓派+Python篇)

    阿里云物联网平台体验(树莓派+Python篇) 虽然对阿里云物联网平台比较熟悉了,从一开始就有幸参与了飞凤平台(Link Develop 一站式开发平台的前身)的一些偏硬件接入的工作.但是同时也见证了 ...

随机推荐

  1. codis集群搭建笔记

    一.安装Linux虚拟机 二.安装go运行环境 https://www.cnblogs.com/xmzncc/p/6218694.html wget http://mirrors.flysnow.or ...

  2. C# 打开mpp文件(Microsoft object)问题总结

    有需求就有解决方案,早上还没有听说过什么是 mpp 文件,下午已经能成功的将功能实现,这难道就是程序员的职业素养?哈哈哈哈 从网上找了很多方法,最后自己找到一个十分简单的打开 mpp 文件的方法: p ...

  3. c# 项目nuget不自动安装dll

    问题 创建的项目提交到服务器上,其他人下载项目后无法生成解决方案成功,无法自动生成dll,无法自动下载安装相应的插件 解决方案 删除packages文件夹即可,nuget就可以自动安装相关的dll了

  4. Java自学-I/O Stream流

    Java的流 Stream 什么是流(Stream),流就是一系列的数据 步骤 1 : 什么是流 当不同的介质之间有数据交互的时候,JAVA就使用流来实现. 数据源可以是文件,还可以是数据库,网络甚至 ...

  5. 349套HTML5+CSS3各行各业网站模板免费下载

    场景 349套HTML5+CSS3各行各业网站模板. Web前端开发是从网页制作演变而来的,名称上有很明显的时代特征.在互联网的演化进程中,网页制作是Web1.0时代产物,那时网站的主要内容是静态的, ...

  6. web的应用模式

    在开发web应用中,有两种模式: 1.前后端分离. 2.前后端不分离. 一.前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果是有后端控制的,由后端渲染页面或重定向,也就是后端需要控制前端的 ...

  7. 完整的房间类游戏解决方案AiJ

    介绍 AiJ是一套完整的房间类游戏解决方案,支持无限水平扩展来满足更大的人数承载,并且提供了良好的调试接口. 主要模块包括: 注册中心 大厅服务 游戏服务 亲友圈服务 运营管理系统 CocosCrea ...

  8. XGBoost 引入 - 提升树

    认识提升树 这个boosting 跟 Adaboost 不同. Adaboost 是通过上一轮的误差率来动态给定一下轮样本不同的权重来学习不同的模型. 现在的方式, 更多是基于残差 的方式来训练. 一 ...

  9. 我是这样手写Spring的,麻雀虽小五脏俱全

    人见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十 ...

  10. Python3和HTMLTestRunner生成html测试报告

    1.测试环境: Python3.5+unittest+HTMLTestRunner 2.下载HTMLTestRunner.py文件 下载地址 http://tungwaiyip.info/softwa ...