全部产品

API校验规范

更新时间:2017-06-07 13:26:11   分享:   

欢迎使用智能对话平台API

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

API整体检验规则

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

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

签名计算方法

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 客户端需要的返回类型 字符串

下面提供了几种常用语言的签名方法:

  • Node.js

    1. var http = require('http')
    2. var qs = require('querystring')
    3. var crypto = require('crypto')
    4. var url = require('url')
    5. function http_proxy(ak_id, ak_secret) {
    6. this.ak_id = ak_id;
    7. this.ak_secret = ak_secret;
    8. this.current_gmt_time = function() {
    9. return new Date().toGMTString();
    10. };
    11. this.md5_base64 = function(strbody) {
    12. let md5hash = crypto.createHash('md5');
    13. md5hash.update(strbody);
    14. return md5hash.digest().toString('base64');
    15. };
    16. this.sha1_base64 = function(str_to_sign) {
    17. return crypto.createHmac('sha1', this.ak_secret).update(str_to_sign).digest().toString('base64');
    18. };
    19. this.send_request = function(queryurl, body) {
    20. let gmtnow = this.current_gmt_time();
    21. let jsonbody = JSON.stringify(body);
    22. let body_md5 = this.md5_base64(jsonbody);
    23. let str_to_sign = "POST\napplication/json\n" + body_md5 + "\napplication/json\n" + gmtnow;
    24. let signature = this.sha1_base64(str_to_sign, this.ak_secret);
    25. let auth_header = "Dataplus " + ak_id + ":" + signature;
    26. urldata = url.parse(queryurl);
    27. let options = {
    28. host: urldata.host,
    29. path: urldata.path,
    30. port: 80,
    31. method: 'POST',
    32. headers : {
    33. 'Accept' : 'application/json',
    34. 'Content-Type' : 'application/json',
    35. 'Date': gmtnow,
    36. 'Authorization': auth_header
    37. }
    38. };
    39. let req = http.request(options, function(res) {
    40. console.log('STATUS: ' + res.statusCode);
    41. res.setEncoding('utf8')
    42. res.on('data', function(chunk) {
    43. console.log('BODY: ' + chunk);
    44. })
    45. });
    46. req.on('error', function(e) {
    47. console.log('problem with request:' + e.message);
    48. });
    49. req.write(jsonbody);
    50. req.end();
    51. }
    52. }
    53. module.exports = http_proxy;
  • Java

    1. import java.io.IOException;
    2. import java.io.InputStream;
    3. import java.io.InputStreamReader;
    4. import java.io.OutputStream;
    5. import java.io.Reader;
    6. import java.io.StringWriter;
    7. import java.io.UnsupportedEncodingException;
    8. import java.io.Writer;
    9. import java.net.HttpURLConnection;
    10. import java.net.URL;
    11. import java.security.MessageDigest;
    12. import java.text.SimpleDateFormat;
    13. import java.util.Date;
    14. import java.util.Locale;
    15. import javax.crypto.Mac;
    16. import javax.crypto.spec.SecretKeySpec;
    17. public class HttpProxy {
    18. //计算MD5+BASE64
    19. public static String MD5Base64(String s) throws UnsupportedEncodingException {
    20. if (s == null) {
    21. return null;
    22. }
    23. String encodeStr = "";
    24. //string 编码必须为utf-8
    25. byte[] utfBytes = s.getBytes("UTF-8");
    26. MessageDigest mdTemp;
    27. try {
    28. mdTemp = MessageDigest.getInstance("MD5");
    29. mdTemp.update(utfBytes);
    30. byte[] md5Bytes = mdTemp.digest();
    31. encodeStr = Base64.encode(md5Bytes);
    32. } catch (Exception e) {
    33. throw new Error("Failed to generate MD5 : " + e.getMessage());
    34. }
    35. return encodeStr;
    36. }
    37. //计算 HMAC-SHA1
    38. public static String HMACSha1(String data, String key) {
    39. String result;
    40. try {
    41. SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
    42. Mac mac = Mac.getInstance("HmacSHA1");
    43. mac.init(signingKey);
    44. byte[] rawHmac = mac.doFinal(data.getBytes());
    45. result = Base64.encode(rawHmac);
    46. } catch (Exception e) {
    47. throw new Error("Failed to generate HMAC : " + e.getMessage());
    48. }
    49. return result;
    50. }
    51. public static String toGMTString(Date date) {
    52. SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.UK);
    53. df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));
    54. return df.format(date);
    55. }
    56. //发送请求
    57. public static String sendRequest(String url, String body, String ak_id, String ak_secret) {
    58. OutputStream out = null;
    59. InputStream in = null;
    60. HttpURLConnection conn = null;
    61. String result = "";
    62. try {
    63. URL realUrl = new URL(url);
    64. //http header 参数
    65. String method = "POST";
    66. String accept = "application/json";
    67. String content_type = "application/json";
    68. String date = toGMTString(new Date());
    69. // 1.对body做MD5+BASE64加密
    70. String bodyMd5 = MD5Base64(body);
    71. String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date ;
    72. // 2.计算 HMAC-SHA1
    73. String signature = HMACSha1(stringToSign, ak_secret);
    74. // 3.得到 authorization header
    75. String authHeader = "Dataplus " + ak_id + ":" + signature;
    76. conn = (HttpURLConnection) realUrl.openConnection();
    77. conn.setRequestMethod(method);
    78. conn.setRequestProperty("Accept", accept);
    79. conn.setRequestProperty("Content-Type", content_type);
    80. conn.setRequestProperty("Date", date);
    81. conn.setRequestProperty("Authorization", authHeader);
    82. conn.setDoOutput(true);
    83. conn.setDoInput(true);
    84. out = conn.getOutputStream();
    85. write(body, out, "utf-8");
    86. out.flush();
    87. int rc = conn.getResponseCode();
    88. if (rc == 200) {
    89. in = conn.getInputStream();
    90. } else {
    91. in = conn.getErrorStream();
    92. }
    93. result = toString(in, "utf-8");
    94. } catch (Exception e) {
    95. System.out.println("请求异常:" + e);
    96. e.printStackTrace();
    97. }
    98. finally {
    99. try {
    100. if (conn != null) {
    101. conn.disconnect();
    102. }
    103. if (out != null) {
    104. out.close();
    105. }
    106. if (in != null) {
    107. in.close();
    108. }
    109. } catch (IOException ex) {
    110. ex.printStackTrace();
    111. }
    112. }
    113. return result;
    114. }
    115. private static void write(String data, OutputStream output, String encoding)
    116. throws IOException {
    117. if (data != null) {
    118. if (encoding == null) {
    119. write(data, output);
    120. } else {
    121. output.write(data.getBytes(encoding));
    122. }
    123. }
    124. }
    125. private static void write(String data, OutputStream output)
    126. throws IOException {
    127. if (data != null) {
    128. output.write(data.getBytes());
    129. }
    130. }
    131. private static String toString(InputStream input, String encoding)
    132. throws IOException {
    133. StringWriter sw = new StringWriter();
    134. copy(input, sw, encoding);
    135. return sw.toString();
    136. }
    137. private static void copy(InputStream input, Writer output, String encoding)
    138. throws IOException {
    139. if (encoding == null) {
    140. copy(input, output);
    141. } else {
    142. InputStreamReader in = new InputStreamReader(input, encoding);
    143. copy(in, output);
    144. }
    145. }
    146. private static void copy(InputStream input, Writer output)
    147. throws IOException {
    148. InputStreamReader in = new InputStreamReader(input);
    149. copy(in, output);
    150. }
    151. private static int copy(Reader input, Writer output) throws IOException {
    152. long count = copyLarge(input, output);
    153. if (count > Integer.MAX_VALUE) {
    154. return -1;
    155. }
    156. return (int) count;
    157. }
    158. private static long copyLarge(Reader input, Writer output) throws IOException {
    159. char[] buffer = new char[1024 * 4];
    160. long count = 0;
    161. int n = 0;
    162. while (-1 != (n = input.read(buffer))) {
    163. output.write(buffer, 0, n);
    164. count += n;
    165. }
    166. return count;
    167. }
    168. }
  • PHP

    1. <?php
    2. class HttpProxy {
    3. private $akId;
    4. private $akSecret;
    5. public function __construct($akId, $akSecret) {
    6. $this->akId = $akId;
    7. $this->akSecret = $akSecret;
    8. }
    9. private function gmt_time() {
    10. return gmdate("D, d M Y H:i:s \G\M\T");
    11. }
    12. private function md5_base64($strbody) {
    13. return base64_encode(md5($strbody, true));
    14. }
    15. private function sha1_base64($strtosign, $secret) {
    16. return base64_encode(hash_hmac("sha1", $strtosign, $secret, true));
    17. }
    18. public function send_request($url, $post_data) {
    19. $gmtnow = $this->gmt_time();
    20. $jsonbody = json_encode($post_data);
    21. $bodymd5 = $this->md5_base64($jsonbody);
    22. $strtosign = "POST\napplication/json\n" . $bodymd5 . "\napplication/json\n" . $gmtnow;
    23. $signature = $this->sha1_base64($strtosign, $this->akSecret);
    24. $auth_header = "Dataplus " . $this->akId . ":" . $signature;
    25. $header = array('Accept:application/json', 'Content-Type:application/json', 'Date:'.$gmtnow, 'Authorization:'.$auth_header);
    26. $ch = curl_init();
    27. if(substr($url, 0, 5) == "https") {
    28. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    29. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);
    30. }
    31. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    32. curl_setopt($ch, CURLOPT_URL, $url);
    33. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    34. curl_setopt($ch, CURLOPT_POST, true);
    35. curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonbody);
    36. $response = curl_exec($ch);
    37. if($error = curl_error($ch)){
    38. die($error);
    39. }
    40. curl_close($ch);
    41. return $response;
    42. }
    43. }
    44. ?>
  • Python 3.5

    1. #!/usr/bin/python
    2. # -*- coding:utf-8 -*-
    3. import hashlib
    4. import urllib.request
    5. import hmac
    6. import base64
    7. import datetime
    8. import ssl
    9. class http_proxy:
    10. """
    11. Http工具类,封装了鉴权
    12. """
    13. def __init__(self, ak_id, ak_secret):
    14. self.__ak_id = ak_id
    15. self.__ak_secret = ak_secret
    16. def __current_gmt_time(self):
    17. date = datetime.datetime.strftime(datetime.datetime.utcnow(), "%a, %d %b %Y %H:%M:%S GMT")
    18. return date
    19. def __md5_base64(self, strbody):
    20. hash = hashlib.md5()
    21. hash.update(strbody.encode('utf-8'))
    22. print(hash.digest())
    23. return base64.b64encode(hash.digest()).decode('utf-8')
    24. def __sha1_base64(self, str_to_sign, secret):
    25. hmacsha1 = hmac.new(secret.encode('utf-8'), str_to_sign.encode('utf-8'), hashlib.sha1)
    26. return base64.b64encode(hmacsha1.digest()).decode('utf-8')
    27. def send_request(self, url, body):
    28. gmtnow = self.__current_gmt_time()
    29. print(gmtnow)
    30. body_md5 = self.__md5_base64(body)
    31. print(body_md5)
    32. str_to_sign = "POST\napplication/json\n" + body_md5 + "\napplication/json\n" + gmtnow
    33. print(str_to_sign)
    34. signature = self.__sha1_base64(str_to_sign, self.__ak_secret)
    35. print(signature)
    36. auth_header = "Dataplus " + self.__ak_id + ":" + signature
    37. print(auth_header)
    38. ssl._create_default_https_context = ssl._create_unverified_context
    39. req = urllib.request.Request(url)
    40. req.add_header("Accept", "application/json")
    41. req.add_header("Content-Type", "application/json")
    42. req.add_header("Date", gmtnow)
    43. req.add_header("Authorization", auth_header)
    44. data = body.encode('utf-8')
    45. f = urllib.request.urlopen(req, data)
    46. return f.read().decode('utf-8')
  • Go

    1. package utils
    2. import (
    3. "fmt"
    4. "net/http"
    5. "io/ioutil"
    6. "time"
    7. "bytes"
    8. "crypto/md5"
    9. "crypto/hmac"
    10. "crypto/sha1"
    11. "encoding/base64"
    12. )
    13. type HttpProxy struct {
    14. AkId string
    15. AkSecret string
    16. }
    17. func (proxy *HttpProxy)gmttime() string {
    18. location,_ := time.LoadLocation("GMT")
    19. now := time.Now().In(location)
    20. return now.Format("Mon, 02 Jan 2006 15:04:05 GMT")
    21. }
    22. func (proxy *HttpProxy)md5base64(strbody string) string {
    23. m := md5.New()
    24. m.Write([]byte(strbody))
    25. return string(base64.StdEncoding.EncodeToString(m.Sum(nil)))
    26. }
    27. func (proxy *HttpProxy)sha1base64(strToSign string, secret string) string {
    28. key := []byte(secret)
    29. h := hmac.New(sha1.New, key)
    30. h.Write([]byte(strToSign))
    31. return string(base64.StdEncoding.EncodeToString(h.Sum(nil)))
    32. }
    33. func (proxy *HttpProxy)SendRequest(url string, reqBody string) string {
    34. gmtnow := proxy.gmttime()
    35. bodyMd5 := proxy.md5base64(reqBody)
    36. strToSign := "POST\napplication/json\n" + bodyMd5 + "\napplication/json\n" + gmtnow;
    37. signature := proxy.sha1base64(strToSign, proxy.AkSecret)
    38. authHeader := "Dataplus " + proxy.AkId + ":" + signature
    39. client := &http.Client{}
    40. reqBodyBuf := bytes.NewBuffer([]byte(reqBody))
    41. request, _ := http.NewRequest("POST", url, reqBodyBuf)
    42. request.Header.Set("Accept", "application/json")
    43. request.Header.Set("Content-type", "application/json")
    44. request.Header.Set("Date", gmtnow)
    45. request.Header.Set("Authorization", authHeader)
    46. response, _ := client.Do(request)
    47. fmt.Println(response.StatusCode)
    48. respBody,_ := ioutil.ReadAll(response.Body)
    49. return string(respBody)
    50. }
本文导读目录
本文导读目录
以上内容是否对您有帮助?