全部产品
存储与CDN 数据库 域名与网站(万网) 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网 钉钉智能硬件

官方服务API校验规范

更新时间:2017-08-03 16:25:52

欢迎使用数加API

您可以通过调用API来实现对您在数加订购的官方服务的调用

您可以通过发起HTTPS请求来调用API,首先您需要拥有AccessKey( 点击这里创建和管理您的AccessKey),AccessKey相当于您访问阿里云产品的口令,拥有您完整的权限,请您妥善保管、避免泄露,并定期更换您的AccessKey!

API整体的校验规则

API签名包含 公共请求头(HTTP协议header参数)、URL(规范资源)、Body

  1. Authorization = Dataplus AccessKeyId + ":" + Signature
  2. Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )
  3. StringToSign =
  4. //HTTP协议header
  5. HTTP-Verb + "\n" + //GET|POST|PUT...
  6. Accept + "\n" +
  7. Content-MD5 + "\n" + //Body的MD5值放在此处
  8. Content-Type + "\n" +
  9. Date + "\n" +
  10. url

签名计算方法

API请求使用标准的Authorization头来签名自己的请求,请求格式如下:

  1. Authorization: Dataplus AccessKeyId:Signature

签名算法遵循RFC 2104HMAC-SHA1规范,要签名的元素是请求自身的一些参数,由于每个API请求基本不同,所以签名的结果也不尽相同。

公共请求头计算签名

HTTP协议header

计算签名必须包含参数,Accept、Content-Type、Date的值(Content-Length不计入签名),并按顺序排列;若值不存在则以”\n”补齐

名称 含义 类型 默认值
Authorization 用于验证请求合法性的认证信息,采用AccessKeyId:Signature的形式。 字符串 默认值:无
Content-Type RFC 2616中定义的HTTP请求内容类型。 类型:字符串 默认值:无
Date HTTP 1.1协议中规定的GMT时间,例如:Wed, 05 Sep. 2012 23:00:00 GMT 字符串
Accept 客户端需要的返回值类型。 类型:字符串

URL

完整的URL,比如http://127.0.0.1:808/xxx/yyy?a=1&c=2

  1. URL: '/xxx/yyy?a=1&c=2'

Case

  • Node.js
  1. var request = require('request');
  2. var url = require('url');
  3. var crypto = require('crypto');
  4. var date = new Date().toUTCString()
  5. // 这里填写AK和请求
  6. var ak_id = 'NNV..........5jv';
  7. var ak_secret = 'FGs.....................3Zu';
  8. var options = {
  9. url : 'https://shujuapi.aliyun.com/org_code/service_code/api_name?param1=xxx&param2=xxx',
  10. method: 'GET',
  11. body: '',
  12. headers: {
  13. 'accept': 'application/json',
  14. 'content-type': 'application/json',
  15. 'date': date,
  16. 'Authorization': ''
  17. }
  18. };
  19. // 这里填写AK和请求
  20. md5 = function(buffer) {
  21. var hash;
  22. hash = crypto.createHash('md5');
  23. hash.update(buffer);
  24. return hash.digest('base64');
  25. };
  26. sha1 = function(stringToSign, secret) {
  27. var signature;
  28. return signature = crypto.createHmac('sha1', secret).update(stringToSign).digest().toString('base64');
  29. };
  30. // step1: 组stringToSign [StringToSign = #{method}\\n#{accept}\\n#{data}\\n#{contentType}\\n#{date}\\n#{action}]
  31. var body = options.body || '';
  32. var bodymd5;
  33. if(body === void 0 || body === ''){
  34. bodymd5 = body;
  35. } else {
  36. bodymd5 = md5(new Buffer(body));
  37. }
  38. console.log(bodymd5)
  39. var stringToSign = options.method + "\n" + options.headers.accept + "\n" + bodymd5 + "\n" + options.headers['content-type'] + "\n" + options.headers.date + "\n" + url.parse(options.url).path;
  40. console.log("step1-Sign string:", stringToSign);
  41. // step2: 加密 [Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )]
  42. var signature = sha1(stringToSign, ak_secret);
  43. // console.log("step2-signature:", signature);
  44. // step3: 组authorization header [Authorization = Dataplus AccessKeyId + ":" + Signature]
  45. var authHeader = "Dataplus " + ak_id + ":" + signature;
  46. console.log("step3-authorization Header:", authHeader);
  47. options.headers.Authorization = authHeader;
  48. console.log('authHeader', authHeader);
  49. // step4: send request
  50. function callback(error, response, body) {
  51. if (error) {
  52. console.log("error", error)
  53. }
  54. console.log("step4-response body:", response.statusCode, body)
  55. }
  56. request(options, callback);
  • Java
  1. package com.alibaba.vo;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.PrintWriter;
  6. import java.net.URL;
  7. import java.net.URLConnection;
  8. import java.security.MessageDigest;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Date;
  11. import java.util.Locale;
  12. import javax.crypto.spec.SecretKeySpec;
  13. import sun.misc.BASE64Encoder;
  14. import javax.crypto.Mac;
  15. @SuppressWarnings("restriction")
  16. public class AESDecode {
  17. /*
  18. * 计算MD5+BASE64
  19. */
  20. public static String MD5Base64(String s) {
  21. if (s == null)
  22. return null;
  23. String encodeStr = "";
  24. byte[] utfBytes = s.getBytes();
  25. MessageDigest mdTemp;
  26. try {
  27. mdTemp = MessageDigest.getInstance("MD5");
  28. mdTemp.update(utfBytes);
  29. byte[] md5Bytes = mdTemp.digest();
  30. BASE64Encoder b64Encoder = new BASE64Encoder();
  31. encodeStr = b64Encoder.encode(md5Bytes);
  32. } catch (Exception e) {
  33. throw new Error("Failed to generate MD5 : " + e.getMessage());
  34. }
  35. return encodeStr;
  36. }
  37. /*
  38. * 计算 HMAC-SHA1
  39. */
  40. public static String HMACSha1(String data, String key) {
  41. String result;
  42. try {
  43. SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
  44. Mac mac = Mac.getInstance("HmacSHA1");
  45. mac.init(signingKey);
  46. byte[] rawHmac = mac.doFinal(data.getBytes());
  47. result = (new BASE64Encoder()).encode(rawHmac);
  48. } catch (Exception e) {
  49. throw new Error("Failed to generate HMAC : " + e.getMessage());
  50. }
  51. return result;
  52. }
  53. /*
  54. * 等同于javaScript中的 new Date().toUTCString();
  55. */
  56. public static String toGMTString(Date date) {
  57. SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.UK);
  58. df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));
  59. return df.format(date);
  60. }
  61. /*
  62. * 发送POST请求
  63. */
  64. public static String sendPost(String url, String body, String ak_id, String ak_secret) throws Exception {
  65. PrintWriter out = null;
  66. BufferedReader in = null;
  67. String result = "";
  68. int statusCode = 200;
  69. try {
  70. URL realUrl = new URL(url);
  71. /*
  72. * http header 参数
  73. */
  74. String method = "POST";
  75. String accept = "application/json";
  76. String content_type = "application/json";
  77. String path = realUrl.getFile();
  78. String date = toGMTString(new Date());
  79. // 1.对body做MD5+BASE64加密
  80. String bodyMd5 = MD5Base64(body);
  81. String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date + "\n"
  82. + path;
  83. // 2.计算 HMAC-SHA1
  84. String signature = HMACSha1(stringToSign, ak_secret);
  85. // 3.得到 authorization header
  86. String authHeader = "Dataplus " + ak_id + ":" + signature;
  87. // 打开和URL之间的连接
  88. URLConnection conn = realUrl.openConnection();
  89. // 设置通用的请求属性
  90. conn.setRequestProperty("accept", accept);
  91. conn.setRequestProperty("content-type", content_type);
  92. conn.setRequestProperty("date", date);
  93. conn.setRequestProperty("Authorization", authHeader);
  94. // 发送POST请求必须设置如下两行
  95. conn.setDoOutput(true);
  96. conn.setDoInput(true);
  97. // 获取URLConnection对象对应的输出流
  98. out = new PrintWriter(conn.getOutputStream());
  99. // 发送请求参数
  100. out.print(body);
  101. // flush输出流的缓冲
  102. out.flush();
  103. // 定义BufferedReader输入流来读取URL的响应
  104. statusCode = ((HttpURLConnection)conn).getResponseCode();
  105. if(statusCode != 200) {
  106. in = new BufferedReader(new InputStreamReader(((HttpURLConnection)conn).getErrorStream()));
  107. } else {
  108. in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  109. }
  110. String line;
  111. while ((line = in.readLine()) != null) {
  112. result += line;
  113. }
  114. } catch (Exception e) {
  115. e.printStackTrace();
  116. } finally {
  117. try {
  118. if (out != null) {
  119. out.close();
  120. }
  121. if (in != null) {
  122. in.close();
  123. }
  124. } catch (IOException ex) {
  125. ex.printStackTrace();
  126. }
  127. }
  128. if (statusCode != 200) {
  129. throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
  130. }
  131. return result;
  132. }
  133. /*
  134. * GET请求
  135. */
  136. public static String sendGet(String url, String ak_id, String ak_secret) throws Exception {
  137. String result = "";
  138. BufferedReader in = null;
  139. int statusCode = 200;
  140. try {
  141. URL realUrl = new URL(url);
  142. /*
  143. * http header 参数
  144. */
  145. String method = "GET";
  146. String accept = "application/json";
  147. String content_type = "application/json";
  148. String path = realUrl.getFile();
  149. String date = toGMTString(new Date());
  150. // 1.对body做MD5+BASE64加密
  151. // String bodyMd5 = MD5Base64(body);
  152. String stringToSign = method + "\n" + accept + "\n" + "" + "\n" + content_type + "\n" + date + "\n" + path;
  153. // 2.计算 HMAC-SHA1
  154. String signature = HMACSha1(stringToSign, ak_secret);
  155. // 3.得到 authorization header
  156. String authHeader = "Dataplus " + ak_id + ":" + signature;
  157. // 打开和URL之间的连接
  158. URLConnection connection = realUrl.openConnection();
  159. // 设置通用的请求属性
  160. connection.setRequestProperty("accept", accept);
  161. connection.setRequestProperty("content-type", content_type);
  162. connection.setRequestProperty("date", date);
  163. connection.setRequestProperty("Authorization", authHeader);
  164. connection.setRequestProperty("Connection", "keep-alive");
  165. // 建立实际的连接
  166. connection.connect();
  167. // 定义 BufferedReader输入流来读取URL的响应
  168. statusCode = ((HttpURLConnection)connection).getResponseCode();
  169. if(statusCode != 200) {
  170. in = new BufferedReader(new InputStreamReader(((HttpURLConnection)connection).getErrorStream()));
  171. } else {
  172. in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
  173. }
  174. String line;
  175. while ((line = in.readLine()) != null) {
  176. result += line;
  177. }
  178. } catch (Exception e) {
  179. e.printStackTrace();
  180. } finally {
  181. try {
  182. if (in != null) {
  183. in.close();
  184. }
  185. } catch (Exception e) {
  186. e.printStackTrace();
  187. }
  188. }
  189. if (statusCode != 200) {
  190. throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
  191. }
  192. return result;
  193. }
  194. public static void main(String[] args) throws Exception {
  195. // 发送POST请求示例
  196. String ak_id1 = "NMV.............5jv"; //用户ak
  197. String ak_secret1 = "Fgs...............3zu"; // 用户ak_secret
  198. String url = "https://shujuapi.aliyun.com/org_code/service_code/api_name";
  199. String body = "{\"param1\": \"xxx\", \"param2\":\"xxx\"}";
  200. System.out.println("response body:" + sendPost(url, body, ak_id, ak_secret));
  201. // 发送GET请求
  202. String ak_id1 = "NMV.............5jv"; //用户ak
  203. String ak_secret1 = "Fgs...............3zu"; // 用户ak_secret
  204. String url1 = "https://shujuapi.aliyun.com/org_code/service_code/api_name?param1=xxx&param2=xxx";
  205. System.out.println("response body:" + sendGet(url1, ak_id1, ak_secret1));
  206. }
  207. }
  • PHP
  1. <?php
  2. $akId = "*************";
  3. $akSecret = "******************";
  4. //更新api信息
  5. $url = "https://shujuapi.aliyun.com/org_code/service_code/api_name?param1=xxx&param2=xxx";
  6. $options = array(
  7. 'http' => array(
  8. 'header' => array(
  9. 'accept'=> "application/json",
  10. 'content-type'=> "application/json",
  11. 'date'=> gmdate("D, d M Y H:i:s \G\M\T"),
  12. 'authorization' => ''
  13. ),
  14. 'method' => "GET", //可以是 GET, POST, DELETE, PUT
  15. 'content' => '' //如有数据,请用json_encode()进行编码
  16. )
  17. );
  18. $http = $options['http'];
  19. $header = $http['header'];
  20. $urlObj = parse_url($url);
  21. if(empty($urlObj["query"]))
  22. $path = $urlObj["path"];
  23. else
  24. $path = $urlObj["path"]."?".$urlObj["query"];
  25. $body = $http['content'];
  26. if(empty($body))
  27. $bodymd5 = $body;
  28. else
  29. $bodymd5 = base64_encode(md5($body,true));
  30. $stringToSign = $http['method']."\n".$header['accept']."\n".$bodymd5."\n".$header['content-type']."\n".$header['date']."\n".$path;
  31. $signature = base64_encode(
  32. hash_hmac(
  33. "sha1",
  34. $stringToSign,
  35. $akSecret, true));
  36. $authHeader = "Dataplus "."$akId".":"."$signature";
  37. $options['http']['header']['authorization'] = $authHeader;
  38. $options['http']['header'] = implode(
  39. array_map(
  40. function($key, $val){
  41. return $key.":".$val."\r\n";
  42. },
  43. array_keys($options['http']['header']),
  44. $options['http']['header']));
  45. $context = stream_context_create($options);
  46. $file = file_get_contents($url, false, $context );
  47. echo($file);
  48. ?>
  • Python 2.7
  1. #!/usr/bin/python
  2. # -*- coding:utf-8 -*-
  3. from urlparse import urlparse
  4. import datetime
  5. import base64
  6. import hmac
  7. import hashlib
  8. import json
  9. import urllib2
  10. def get_current_date():
  11. date = datetime.datetime.strftime(datetime.datetime.utcnow(), "%a, %d %b %Y %H:%M:%S GMT")
  12. return date
  13. def to_md5_base64(strBody):
  14. hash = hashlib.md5()
  15. hash.update(body)
  16. return hash.digest().encode('base64').strip()
  17. def to_sha1_base64(stringToSign, secret):
  18. hmacsha1 = hmac.new(secret, stringToSign, hashlib.sha1)
  19. return base64.b64encode(hmacsha1.digest())
  20. ak_id = '<用户的AK_ID>'
  21. ak_secret = '<用户的AK_SECRET>'
  22. options = {
  23. 'url': '<请求的url>',
  24. 'method': 'POST',
  25. 'body': json.dumps({"name": "hello"}, separators=(',', ':')),
  26. 'headers': {
  27. 'accept': 'application/json',
  28. 'content-type': 'application/json',
  29. 'date': get_current_date(),
  30. 'authorization': ''
  31. }
  32. }
  33. # options = {
  34. # 'url': '<请求的url>',
  35. # 'method': 'GET',
  36. # 'headers': {
  37. # 'accept': 'application/json',
  38. # 'content-type': 'application/json',
  39. # 'date': get_current_date(), # 'Sat, 07 May 2016 08:19:52 GMT', # get_current_date(),
  40. # 'authorization': ''
  41. # }
  42. # }
  43. body = ''
  44. if 'body' in options:
  45. body = options['body']
  46. print body
  47. bodymd5 = ''
  48. if not body == '':
  49. bodymd5 = to_md5_base64(body)
  50. print bodymd5
  51. urlPath = urlparse(options['url'])
  52. if urlPath.query != '':
  53. urlPath = urlPath.path + "?" + urlPath.query
  54. else:
  55. urlPath = urlPath.path
  56. stringToSign = options['method'] + '\n' + options['headers']['accept'] + '\n' + bodymd5 + '\n' + options['headers']['content-type'] + '\n' + options['headers']['date'] + '\n' + urlPath
  57. signature = to_sha1_base64(stringToSign, ak_secret)
  58. print stringToSign
  59. authHeader = 'Dataplus ' + ak_id + ':' + signature
  60. options['headers']['authorization'] = authHeader
  61. print authHeader
  62. request = None
  63. method = options['method']
  64. url = options['url']
  65. print method
  66. print url
  67. if 'GET' == method or 'DELETE' == method:
  68. request = urllib2.Request(url)
  69. elif 'POST' == method or 'PUT' == method:
  70. request = urllib2.Request(url, body)
  71. request.get_method = lambda: method
  72. for key, value in options['headers'].items():
  73. request.add_header(key, value)
  74. try:
  75. conn = urllib2.urlopen(request)
  76. response = conn.read()
  77. print response
  78. except urllib2.HTTPError, e:
  79. print e.read()
  80. raise SystemExit(e)
本文导读目录