1. 请求签名
1.1.1. 简介
上传相关接口基于密钥 HMAC(Hash Message Authentication Code)的自定义方案进行身份验证。
HTTP 请求时携带签名,服务器端收到消息后,进行身份验证,验证成功则可接受并执行请求,否则将会返回错误信息并丢弃此请求。
1.1.2. 签名实现
使用 Authorization传递签名数据,并放置于各 HTTP 请求的报文头中,如下所示:
Authorization:clientID:signature
其中,signature 是一个哈希值,具体为请求中特定元素的 HMAC-SHA1(RFC2104),因此 signature 会因请求不同而异。如果客户端请求中随附的signature 与服务端计算出的signature 相匹配,则身份校验通过。
以下是 Authorization构造的步骤:
步骤1:组装请求参数HttpParameters
遍历 HTTP 请求参数(Query),生成 key 到 value 的映射 Map 及 key 的列表 KeyList:
key 使用 UrlEncode编码再转换为小写形式。
value 使用UrlEncode编码。若无 value 的参数,则认为 value 为空字符串。例如请求路径为
URL?id&fileNname=sample.jpeg
,则认为是URL?id&fileNname=sample.jpeg
。说明:
HTTP 请求参数,即请求路径中
?
以后的部分,例如请求路径为URL?id&fileNname=sample.jpeg
,则请求参数为id&fileNname=sample.jpeg
。
将 KeyList 按照字典序排序。
按照 KeyList 的顺序用拼接 Map 中的每一个键值对,格式为
key1=value1&key2=value2&key3=value3
,即为 HttpParameters。示例:
POST /v1/upload/uploadFile HTTP/1.1 Host: openapi.xiaozancloud.com Content-MD5: b783e8591eb33219b813e7afb85dc4c3 Content-Length: 102814 Date: Fri, 01 Jan 2021 00:00:00 GMT Content-Type: image/jpeg "<file contents here>"
计算过程:
//key urlencode编码后转小写,value urlencode编码,组装成数组对象,排序后用&拼接为字符串: //因为无Query参数,所以为空 HttpParameters =
步骤2:组装请求头部HttpHeaders
遍历 HTTP 请求头部,生成 key 到 value 的映射 Map 及 key 的列表 KeyList,key转换为小写形式,value去除左右两边的空格符。
将 KeyList 按照字典序排序。
按照 KeyList 的顺序拼接 Map 中的每一个键值对,格式为
key1=value1&key2=value2&key3=value3
,即为 HttpHeaders。只使用以下几种请求头部参与签名:Host、Content-Type、Content-MD5、Content-Length、Date
注:
1)Content-Type:RFC 2616 中定义的 HTTP 请求内容类型(MIME)。无请求体的情况下,如GET请求传空值。
2)Content-MD5:Base64 编码的请求体MD5校验值。无请求体时传空值。
3)Content-Length:请求体的长度,无请求体时传0。
4)Date:格式必须为RFC2822格式,且不能与服务器时间相差超过15分钟。
示例:
POST /v1/upload/uploadFile HTTP/1.1 Host: openapi.xiaozancloud.com Content-MD5: b783e8591eb33219b813e7afb85dc4c3 Content-Length: 102814 Date: Fri, 01 Jan 2021 00:00:00 GMT Content-Type: image/jpeg "<file contents here>"
计算过程:
//key转小写,value去除左右空格,组装成数组对象,排序后用&拼接为字符串: HttpHeaders = content-length=102814&content-md5=b783e8591eb33219b813e7afb85dc4c3&content-type=image%2Fjpeg&date=Fri%2C+01+Jan+2021+00%3A00%3A00+GMT&openapi.xiaozancloud.com
步骤3:生成 StringToSign
根据 HTTP 方法(HttpMethod)、HTTP 请求路径(UriPathname)、 请求参数(HttpParameters)和请求头部(HttpHeaders)通过换行符\n
拼接为 StringToSign,格式为HttpMethod\n
UriPathname\n
HttpParameters\n
HttpHeaders\n
。
其中:
HttpMethod 转换为大写,例如 GET 或 POST。
UriPathname 为请求路径,例如
/
或/v1
。\n
为换行符。如果其中有字符串为空,前后的换行符需要保留,例如GET\n/v1\n\n\n
。计算过程:
StringToSign = POST\n/v1/upload/uploadFile\n\ncontent-length=102814&content-md5=b783e8591eb33219b813e7afb85dc4c3&content-type=image%2Fjpeg&date=Fri%2C+01+Jan+2021+00%3A00%3A00+GMT&openapi.xiaozancloud.com
步骤4:生成 Signature
使用HMAC-SHA1 以 ClientSecret为密钥(字符串形式,非原始二进制),以StringToSign为消息,计算消息摘要HmacString,再base64运算:
假设:
ClientID = 48ca17b00473d5e595ab ClientSecret = 48ca17b00473d5e595ab48ca17b00473d5e595ab48ca17b00473d5e595ab
HmacString = hmac-sha1(ClientSecret, String2sign) = dabeac3144c9fa1876edd7c9716748f83dd1628a Base64String = base64(HmacString) = ZGFiZWFjMzE0NGM5ZmExODc2ZWRkN2M5NzE2NzQ4ZjgzZGQxNjI4YQ==
Base64String通过冒号
:
与ClientID拼接生成签名Authorization:Authorization = ClientID:Base64String = 48ca17b00473d5e595ab:ZGFiZWFjMzE0NGM5ZmExODc2ZWRkN2M5NzE2NzQ4ZjgzZGQxNjI4YQ==