数据平台Open-API调用鉴权说明

构造签名signature

签名的过程是将请求参数串以及APP密钥根据一定签名算法生成的签名值,作为新的请求参数从而提高访问过程中的防篡改性。

参数 说明
AccessId, SecretKey 每一个客户端接入之前随机分配的
1. 做验证是计算使用。
2. 方便以后启用/停用任意一个api来源
Date 时间戳。服务器根据这个时间来判断生成的签名是否过期
/itask/users?zone=beijing&page_size=10
signature 一个不可逆算法,一般是sha1/md5等
  • 其中AccessId相当于帐号,是公开的;SecretKey相当于密码,只有平台和开发者自己知道。开发者绝不能将SecretKey包含在http请求中

在header中包含签名

调用端可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息

Authorization字段计算的方法


Authorization = "IWOP " + AccessId + ":" + Signature
Signature = base64(HmacSha1(SecretKey,
            VERB + "\n"
            + ContentType + "\n"
            + Date + "\n"
            + ""
            + CanonicalizedResource))
  • Authorization = "IWOP" + 空格 + AccessId + ":" + 签名
  • SecretKey 表示签名所需的密钥
  • VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等
  • \n 表示换行符
  • Content-Type 表示请求内容的类型,如"application/octet-stream",如果请求头不包含Content-Type,这该值为空
  • Date 表示此次操作的时间,且必须为GMT格式,如'Fri, 02 Feb 2018 10:44:35 GMT'。客户端时间与平台时间不能相关太大,如果相差超过15分钟,平台会拒绝执行
  • CanonicalizedResource 表示用户想要访问的iwop资源

其中,VERB、Date和CanonicalizedResource不能为空;如果请求中的Date时间和平台服务器的时间差15分钟以上,平台服务器将拒绝该服务,并返回HTTP 403错误。

构建CanonicalizedResource的方法

用户发送请求中想访问的iwop目标资源被称为CanonicalizedResource。它的构建方法如下:

  1. 将CanonicalizedResource置成空字符串 "";
  2. 添加要访问的api的path部分(前面示例中的 '/itask/users')
  3. 如果请求包含了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照字典顺序,从小到大排列,以&为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource为:http://api.mctech.vip/itask/users?page_size=10&zone=beijing

  4. 注意生成的CanonicalizedResource中page_size与zone两参数已经按字母顺序重排了

计算签名头规则

  1. 签名的字符串必须为UTF-8格式。含有中文字符的签名字符串必须先进行UTF-8编码,再与SecretKey计算最终签名。
  2. 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 SecretKey
  3. 在http请求中Content-Type不是必须的,如果请求头中没有提供Content-Type,在签名算法的对应项中以空值('')替换,此处结尾的换行符\n需要省略。
  4. 在所有非HTTP标准定义的header中,只有以 x-iwop- 开头的header,需要加入签名字符串;其他非HTTP标准header将被平台忽略(如上例中的x-iwop-name是需要加入签名字符串的)。
  5. x-iwop-开头的header在签名验证前需要符合以下规范:
    • header的名字需要变成小写。
    • header按字典序自小到大排序。
    • 分割header name和value的冒号前后不能有空格。
    • 每个header之后都有一个换行符\n,如果没有以x-iwop-开头的header,CanonicalizedIWOPHeaders就设置为空。

签名示例

假如AccessId是'Hb18J9rjxX7ibdqw7DWv',SecretKey是'9rjxX7ibdqw7DWvfuldrfiiBnqTan9TrXUFOwNm2'

请求 签名字符串计算公式 签名字符串
GET /itask/users?zone=beijing&page_size=10
Content-Type: text/html
Accepts: aplication/json,*/*
Date: Fri, 02 Feb 2018 10:44:35 GMT
Host: api.mctech.vip
Signature = base64(HmacSha1(SecretKey,
 VERB + '\n'
 + Content-Type + '\n'+ Date + '\n'
 + CanonicalizedIWOPHeaders
 + CanonicalizedResource))
'GET\ntext/html\nFri, 02 Feb 2018 10:44:35 GMT\n/itask/users?page_size=10&zone=beijing'

可用以下方法计算签名(Signature):

  • javascript
const CryptoJS = require('crypto-js')
let content = 'GET\ntext/html\nFri, 02 Feb 2018 10:44:35 GMT\nhttp://api.mctech.vip/itask/users?page_size=10&zone=beijing'
let secretKey = '9rjxX7ibdqw7DWvfuldrfiiBnqTan9TrXUFOwNm2'
// crypto-js 模块内部默认使用utf-8编码
let data = CryptoJS.HmacSHA1(content, secretKey)
let signature = data.toString(CryptoJS.enc.Base64)
console.log(signature)
  • java
Charset utf8 = Charset.forName(CHARSET_UTF8)
String content = "GET\ntext/html\nFri, 02 Feb 2018 10:44:35 GMT\nhttp://api.mctech.vip/itask/users?page_size=10&zone=beijing"
String secretKey = "9rjxX7ibdqw7DWvfuldrfiiBnqTan9TrXUFOwNm2"
byte[] contentBytes = content.getBytes(utf8);
byte[] secretKeyBytes = secretKey.getBytes(utf8);

SecretKey signingKey = new SecretKeySpec(secretKeyBytes, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);

byte[] signatureBytes = mac.doFinal(contentBytes);
String signature = new BASE64Encoder().encode(signatureBytes);
System.out.print(signature);

生成Authorization头

上面例子签名(Signature)计算结果应该为 'Jxszg5LHZwnLgI/5dQuVAQVT5Bs=',因为Authorization = 'IWOP ' + AccessId + ':' + Signature

而AccessId为'Hb18J9rjxX7ibdqw7DWv'

所以最后Authorization为 'IWOP Hb18J9rjxX7ibdqw7DWv:Jxszg5LHZwnLgI/5dQuVAQVT5Bs='

然后加上Authorization头来组成最后需要发送的消息:

GET /itask/users?zone=beijing&page_size=10
Authorization: IWOP Hb18J9rjxX7ibdqw7DWv:Jxszg5LHZwnLgI/5dQuVAQVT5Bs=
Content-Type: text/html
Date: Fri, 02 Feb 2018 10:44:35 GMT
Host: api.mctech.vip

返回结果

  1. 如果传入的AccessId不存在或被禁用了,返回403 Forbidden。错误码:InvalidAccessId。
  2. 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。
  3. IWOP所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。
  4. 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。
  5. 传入请求的时间(Date)必须在服务器当前时间之后的10分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。
  6. 返回示例:
<?xml version="1.0" ?>
<Error>
 <Code>SignatureDoesNotMatch</Code>
 <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
 <StringToSignBytes>58 69 66 6f 73 66 59 37 71 48 64 77 42 31 4d 55 4f 70 35 46 31 47 44 51 55 55 63 3d</StringToSignBytes>
 <SignatureProvided>y5H7yzPsA/tP4+0tH1HHvPEwUv8=</SignatureProvided>
 <StringToSign>
GET
text/html
Fri, 02 Feb 2018 10:44:35 GMT
/itask/users?`page_size`=10&`zone`=beijing
 </StringToSign>
 <IWOPAccessId>Hb18J9rjxX7ibdqw7DWv</IWOPAccessId>
</Error>
Copyright © 北京梦诚科技有限公司 2020 all right reserved,powered by Gitbook该文件修订时间: 2022-08-25 11:05:18

results matching ""

    No results matching ""