阿里云
发表主题 回复主题
  • 1483阅读
  • 2回复

REST API鉴权

级别: 论坛粉丝
发帖
1296
云币
2596
— 本帖被 不靠谱贝贝 从 数加 移动到本区(2017-11-01) —


鉴权方法说明


通过RESTful API调用智能语音服务,首先您需要拥有AccessKey( 点击这里创建和管理您的AccessKey),AccessKey相当于您访问阿里产品的口令,拥有您完整的权限,请您妥善保管、避免泄露,并定期更换您的AccessKey!

1. 鉴权请求构造

  • 智能语音服务采用的鉴权方式与阿里云数加鉴权相似,但实现上稍有区别,主要是请求URL不参与鉴权
  • 鉴权签名是指构造一个Authorization字段,并设置到HTTP的Header当中。服务端通过验证Authorization是否正确来确认请求来授权用户。


1.1 整体校验规则

  1. Authorization =  Dataplus AccessKeyId + ":" + Signature
  2. Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) ) //具体实现参考1.2
  3. StringToSign =
  4.   //HTTP协议header
  5.   Method + "\n" +  // POST|GET|PUT...
  6.   Accept + "\n" +
  7.   Body-Digest + "\n" + // Base64(Md5(body))
  8.   Content-Type + "\n" +
  9.   Date ;
  10.   //注意官方鉴权中的url在NLS服务不参与鉴权签名


1.2 签名计算方法


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

签名算法遵循RFC 2104HMAC-SHA1规范,要签名的元素是请求自身的一些参数,由于每个API请求基本不同,所以签名的结果也不尽相同。
在鉴权过程中参与的字段信息,所有字符的编码格式请采用UTF-8,并按顺序排列;若值不存在则以”\n”补齐。
参与签名字段如下:
类型名描述
methodStringHttp请求类型,可以是 GET, POST, DELETE, PUT
acceptString定义http接收的返回值类型
content-typeString定义http发送的数据类型
bodyStringString请求数据,POST请求应该放置于http body中
dateStringHTTP 1.1协议中规定的GMT时间,例如:Wed, 05 Sep. 2012 23:00:00GMT,请注意同步网络时间,上下在5秒钟以内


1.2.1 计算body的MD5及Base64编码

  1. //以java为例
  2. String bodyMd5 = MD5Base64(body);

  • POST/PUT请求body为string 类型非空字符串:计算body的MD5,再将MD5值做Base64编码。
  • body为空:将bodyMd5设为””,即空字符串。
  • body为RESTASR中二进制语音:需要对语音做两次MD5Base64操作,bodyMd5 =MD5Base64(MD5Base64(body))。

GET/DELETE请求
  • 将bodyMd5设为””,即空字符串。


1.2.2 拼装请求验证串

  1. String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date ;
  • RESTASR接口content_type为『”audio/“+audioFormat+”;samplerate=”+sampleRate;』;
  • 批量测试接口content_type为『multipart/form-data』。


1.2.3 计算Authorization


把1.2.2 中得到的stringToSign与Access Secret一起计算HMAC-SHA1后取Base64的值,然后与AccessId一起拼装为Authorization。Authorization会放在HTTP的Header中。
  1. // 1.计算 HMAC-SHA1
  2. String signature = HMACSha1(stringToSign, ak_secret);
  3. // 2.得到 authorization
  4. String authorization = "Dataplus " + ak_id + ":" + signature;


1.3 鉴权签名范例


为了方便用户校验自己的鉴权模块是否正确,我们给出一个鉴权签名范例。我们以POST请求为例,传入一个String类型字符串”Alibaba”作为body值参与鉴权。我们设置鉴权的几个字段值如下:
  1. String method = "POST";
  2. String accept = "application/json";
  3. String content_type = "application/json";
  4. String Date = "Wed, 31 May 2017 08:51:26 GMT";


1.3.1 计算body的MD5及Base64编码


计算”Alibaba”的MD5Base64的值为:”AsdYv2nI4ijTfKYmKX4h/Q==”。
  1. public static String MD5Base64(String s) throws UnsupportedEncodingException {
  2.         if (s == null) {
  3.             return null;
  4.         }
  5.         if (s == ""){
  6.             return "";
  7.         }
  8.         String encodeStr = "";
  9.         //string 编码必须为utf-8
  10.         byte[] utfBytes = s.getBytes("UTF-8");
  11.         MessageDigest mdTemp;
  12.         try {
  13.             mdTemp = MessageDigest.getInstance("MD5");
  14.             mdTemp.update(utfBytes);
  15.             byte[] md5Bytes = mdTemp.digest();
  16.             BASE64Encoder b64Encoder = new BASE64Encoder();
  17.             encodeStr = b64Encoder.encode(md5Bytes);
  18.         } catch (Exception e) {
  19.             throw new Error("Failed to generate MD5 : " + e.getMessage());
  20.         }
  21.         return encodeStr;
  22.     }


1.3.2 拼装请求验证串


拼装stringToSign的值为:“POST\napplication/json\nAsdYv2nI4ijTfKYmKX4h/Q==\napplication/json\nWed,31 May 2017 08:51:26 GMT”。
  1. String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date;


1.3.3 计算Authorization


计算stringToSign和Access secret 的鉴权值为:signature =“nPuAlFx4pPPsGT55oXeigM60paw=”。
  1. String signature = HMACSha1(stringToSign, ak_secret);
  2. public static String HMACSha1(String data, String key) {
  3.         String result;
  4.         try {
  5.             SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
  6.             Mac mac = Mac.getInstance("HmacSHA1");
  7.             mac.init(signingKey);
  8.             byte[] rawHmac = mac.doFinal(data.getBytes());
  9.             result = (new BASE64Encoder()).encode(rawHmac);
  10.         } catch (Exception e) {
  11.             throw new Error("Failed to generate HMAC : " + e.getMessage());
  12.         }
  13.         return result;
  14.     }


2. 请求与响应



2.1 请求


NLS REST服务基于标准的HTTP协议,可设置的值包含Header和Body等。

2.1.1 设置Header

名称含义类型是否必须
Authorization用于验证请求合法性的认证信息,采用AccessKeyId:Signature的形式。字符串
Content-TypeRFC 2616中定义的HTTP请求内容类型。字符串
DateHTTP 1.1协议中规定的GMT时间,例如:Wed, 05 Sep. 2012 23:00:00 GMT字符串
Accept客户端需要的返回值类型。字符串
Content-Lengthbody长度int否,REST ASR服务中必须设置
  • RESTASR接口content_type为『”audio/“+audioFormat+”;samplerate=”+sampleRate;』;
  • 批量测试接口content_type为『multipart/form-data』。
  • RESTTTS接口content_type为『”audio/“+audioFormat+”;samplerate=”+sampleRate;』;


2.1.2 设置Body


根据Content-Type的不同,body的参数也各有不同:
类型说明
application/jsonString类型json
text/plainString类型文本,tts合成使用
audio/*byte[]二进制语音数据
multipart/form-dataform表单


2.2 响应

  • HTTP状态200表示请求成功
  • HTTP状态4XX表示客户端错误,并在body中写明具体错误码和错误消息(error_code,error_message)
  • HTTP状态5XX表示服务端错误,并在body中写明具体错误码和错误消息(error_code,error_message)
  • 若响应格式为JSON格式,JSON结构中会包含request_id字段,用来区分每次请求(一些老的API使用id做为请求标识)

错误消息示例
  1. {
  2.     "id": "be053bf9af0e406dafa8249631372d53",
  3.     "request_id": "be053bf9af0e406dafa8249631372d53",
  4.     "error_code": 080101,
  5.     "error_message": "REQUEST_PARSE_ERROR(Failed to parse json object!)"
  6. }

为了兼容旧API,错误响应中同时包含request_id和id,值相同,后续版本会移除id字段。


2.3 参数类型和参数值类型


参数类型表示该参数出现的位置
类型名描述
Header表明该参数是出现在HTTP请求的Header中
Path表明该参数是url路径的一部分,例如/customizations/{customization_id}
Query表明该参数是url的的查询参数,例如/customizations?base_model=ime
Body表明该参数为HTTP请求的body部分

参数值类型表示该参数的数据类型
类型名描述
String字符串类型
Integer整数类型
Double浮点数类型
Object对象类型,可以有自定义属性
Type[]数组类型,如String[],Object[]


附录 各语言编程范例



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.         //编码为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.             BASE64Encoder b64Encoder = new BASE64Encoder();
  32.             encodeStr = b64Encoder.encode(md5Bytes);
  33.         } catch (Exception e) {
  34.             throw new Error("Failed to generate MD5 : " + e.getMessage());
  35.         }
  36.         return encodeStr;
  37.     }
  38.     /*
  39.      * 计算 HMAC-SHA1
  40.      */
  41.     public static String HMACSha1(String data, String key) {
  42.         String result;
  43.         try {
  44.             SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
  45.             Mac mac = Mac.getInstance("HmacSHA1");
  46.             mac.init(signingKey);
  47.             byte[] rawHmac = mac.doFinal(data.getBytes());
  48.             result = (new BASE64Encoder()).encode(rawHmac);
  49.         } catch (Exception e) {
  50.             throw new Error("Failed to generate HMAC : " + e.getMessage());
  51.         }
  52.         return result;
  53.     }
  54.     /*
  55.      * 等同于javaScript中的 new Date().toUTCString();
  56.      */
  57.     public static String toGMTString(Date date) {
  58.         SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.UK);
  59.         df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));
  60.         return df.format(date);
  61.     }
  62.     /*
  63.      * 发送POST请求
  64.      */
  65.     public static String sendPost(String url, String body, String ak_id, String ak_secret) throws Exception {
  66.         PrintWriter out = null;
  67.         BufferedReader in = null;
  68.         String result = "";
  69.         int statusCode = 200;
  70.         try {
  71.             URL realUrl = new URL(url);
  72.             /*
  73.              * http header 参数
  74.              */
  75.             String method = "POST";
  76.             String accept = "json";
  77.             String content_type = "application/json";
  78.             String path = realUrl.getFile();
  79.             String date = toGMTString(new Date());
  80.             String bodyMd5 = "";
  81.             // 1.对body做MD5+BASE64加密
  82.             if(body != null && body != ""){
  83.                 bodyMd5 = MD5Base64(body);
  84.             }
  85.             String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date ;
  86.             // 2.计算 HMAC-SHA1
  87.             String signature = HMACSha1(stringToSign, ak_secret);
  88.             // 3.得到 authorization header
  89.             String authHeader = "Dataplus " + ak_id + ":" + signature;
  90.             // 打开和URL之间的连接
  91.             URLConnection conn = realUrl.openConnection();
  92.             // 设置通用的请求属性
  93.             conn.setRequestProperty("accept", accept);
  94.             conn.setRequestProperty("content-type", content_type);
  95.             conn.setRequestProperty("date", date);
  96.             conn.setRequestProperty("Authorization", authHeader);
  97.             // 发送POST请求必须设置如下两行
  98.             conn.setDoOutput(true);
  99.             conn.setDoInput(true);
  100.             // 获取URLConnection对象对应的输出流
  101.             out = new PrintWriter(conn.getOutputStream());
  102.             // 发送请求参数
  103.             out.print(body);
  104.             // flush输出流的缓冲
  105.             out.flush();
  106.             // 定义BufferedReader输入流来读取URL的响应
  107.             statusCode = ((HttpURLConnection)conn).getResponseCode();
  108.             if(statusCode != 200) {
  109.                 in = new BufferedReader(new InputStreamReader(((HttpURLConnection)conn).getErrorStream()));
  110.             } else {
  111.                 in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  112.             }
  113.             String line;
  114.             while ((line = in.readLine()) != null) {
  115.                 result += line;
  116.             }
  117.         } catch (Exception e) {
  118.             e.printStackTrace();
  119.         } finally {
  120.             try {
  121.                 if (out != null) {
  122.                     out.close();
  123.                 }
  124.                 if (in != null) {
  125.                     in.close();
  126.                 }
  127.             } catch (IOException ex) {
  128.                 ex.printStackTrace();
  129.             }
  130.         }
  131.         if (statusCode != 200) {
  132.             throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
  133.         }
  134.         return result;
  135.     }
  136.     /*
  137.      * GET请求
  138.      */
  139.     public static String sendGet(String url, String ak_id, String ak_secret) throws Exception {
  140.         String result = "";
  141.         BufferedReader in = null;
  142.         int statusCode = 200;
  143.         try {
  144.             URL realUrl = new URL(url);
  145.             /*
  146.              * http header 参数
  147.              */
  148.             String method = "GET";
  149.             String accept = "json";
  150.             String content_type = "application/json";
  151.             String path = realUrl.getFile();
  152.             String date = toGMTString(new Date());
  153.             // 1.对body做MD5+BASE64加密
  154.             // String bodyMd5 = MD5Base64(body);
  155.             String stringToSign = method + "\n" + accept + "\n" + "" + "\n" + content_type + "\n" + date ;
  156.             // 2.计算 HMAC-SHA1
  157.             String signature = HMACSha1(stringToSign, ak_secret);
  158.             // 3.得到 authorization header
  159.             String authHeader = "Dataplus " + ak_id + ":" + signature;
  160.             // 打开和URL之间的连接
  161.             URLConnection connection = realUrl.openConnection();
  162.             // 设置通用的请求属性
  163.             connection.setRequestProperty("accept", accept);
  164.             connection.setRequestProperty("content-type", content_type);
  165.             connection.setRequestProperty("date", date);
  166.             connection.setRequestProperty("Authorization", authHeader);
  167.             connection.setRequestProperty("Connection", "keep-alive");
  168.             // 建立实际的连接
  169.             connection.connect();
  170.             // 定义 BufferedReader输入流来读取URL的响应
  171.             statusCode = ((HttpURLConnection)connection).getResponseCode();
  172.             if(statusCode != 200) {
  173.                 in = new BufferedReader(new InputStreamReader(((HttpURLConnection)connection).getErrorStream()));
  174.             } else {
  175.                 in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
  176.             }
  177.             String line;
  178.             while ((line = in.readLine()) != null) {
  179.                 result += line;
  180.             }
  181.         } catch (Exception e) {
  182.             e.printStackTrace();
  183.         } finally {
  184.             try {
  185.                 if (in != null) {
  186.                     in.close();
  187.                 }
  188.             } catch (Exception e) {
  189.                 e.printStackTrace();
  190.             }
  191.         }
  192.         if (statusCode != 200) {
  193.             throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
  194.         }
  195.         return result;
  196.     }
  197.     public static void main(String[] args) throws Exception {
  198.         // 发送POST请求示例
  199.         String ak_id1 = "NMV.............5jv"; //用户ak
  200.         String ak_secret1 = "Fgs...............3zu"; // 用户ak_secret
  201.         String url = "https://shujuapi.aliyun.com/org_code/service_code/api_name";
  202.         String body = "{\"param1\": \"xxx\", \"param2\":\"xxx\"}";
  203.         System.out.println("response body:" + sendPost(url, body, ak_id, ak_secret));
  204.         // 发送GET请求
  205.         String ak_id1 = "NMV.............5jv"; //用户ak
  206.         String ak_secret1 = "Fgs...............3zu"; // 用户ak_secret
  207.         String url1 = "https://shujuapi.aliyun.com/org_code/service_code/api_name?param1=xxx&param2=xxx";
  208.         System.out.println("response body:" + sendGet(url1, ak_id1, ak_secret1));
  209.     }
  210. }


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'];
  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. ?>


Python2.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.encode('utf-8'))
  16.     return hash.digest().encode('base64').strip()
  17. def to_sha1_base64(stringToSign, secret):
  18.     hmacsha1 = hmac.new(secret.encode('utf-8'), stringToSign.encode('utf-8'), hashlib.sha1)
  19.     return base64.b64encode(hmacsha1.digest()).decode('utf-8')
  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. # REST ASR 接口,需要做两次鉴权
  52. #bodymd5 = to_md5_base64(bodymd5)
  53. stringToSign = options['method'] + '\n' + options['headers']['accept'] + '\n' + bodymd5 + '\n' + options['headers']['content-type'] + '\n' + options['headers']['date']
  54. signature = to_sha1_base64(stringToSign, ak_secret)
  55. print stringToSign
  56. authHeader = 'Dataplus ' + ak_id + ':' + signature
  57. options['headers']['authorization'] = authHeader
  58. print authHeader
  59. request = None
  60. method = options['method']
  61. url = options['url']
  62. print method
  63. print url
  64. if 'GET' == method or 'DELETE' == method:
  65.     request = urllib2.Request(url)
  66. elif 'POST' == method or 'PUT' == method:
  67.     request = urllib2.Request(url, body)
  68. request.get_method = lambda: method
  69. for key, value in options['headers'].items():
  70.     request.add_header(key, value)
  71. try:
  72.     conn = urllib2.urlopen(request)
  73.     response = conn.read()
  74.     print response
  75. except urllib2.HTTPError, e:
  76.     print e.read()
  77.     raise SystemExit(e)


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.       }


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}]
  31. var body = options.body || '';
  32. var bodymd5;
  33. if(body === void 0 || body === ''){
  34.   bodymd5 = '';
  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;
  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);
级别: 新人
发帖
2
云币
2
只看该作者 沙发  发表于: 09-05
ReREST API鉴权
1.3.3 计算Authorization
报错了
Caused by: java.lang.Error: Failed to generate HMAC : null
请问这是怎么回事??怎么解决????
级别: 新人
发帖
2
云币
2
只看该作者 板凳  发表于: 09-05
回 1楼犸云的帖子
看到这个错误信息,不知所云
发表主题 回复主题
« 返回列表上一主题下一主题

限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
验证问题: ECS是阿里云提供的什么服务? 正确答案:云服务器
上一个 下一个