阿里云 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 | 四种运行其他程序的黑科