鉴权方法说明
通过RESTful API调用智能语音服务,首先您需要拥有AccessKey( 点击
这里创建和管理您的AccessKey),AccessKey相当于您访问阿里云产品的口令,拥有您完整的权限,请您妥善保管、避免泄露,并定期更换您的AccessKey!
1. 鉴权请求构造
- 智能语音服务采用的鉴权方式与阿里云数加鉴权相似,但实现上稍有区别,主要是请求URL不参与鉴权。
- 鉴权签名是指构造一个Authorization 字段,并设置到HTTP的Header当中。服务端通过验证Authorization是否正确来确认请求来自授权用户。
1.1 整体校验规则
<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- Authorization = Dataplus AccessKeyId + ":" + Signature
- Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) ) //具体实现参考1.2
- StringToSign =
- //HTTP协议header
- Method + "\n" + // POST|GET|PUT...
- Accept + "\n" +
- Body-Digest + "\n" + // Base64(Md5(body))
- Content-Type + "\n" +
- Date ;
- //注意官方鉴权中的url在NLS服务不参与鉴权签名
1.2 签名计算方法
API请求使用标准的Authorization头来签名自己的请求,请求格式如下:<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- Authorization: Dataplus AccessKeyId:Signature
签名算法遵循RFC 2104HMAC-SHA1规范,要签名的元素是请求自身的一些参数,由于每个API请求基本不同,所以签名的结果也不尽相同。
在鉴权过程中参与的字段信息,所有字符的编码格式请采用UTF-8,并按顺序排列;若值不存在则以”\n”补齐。
参与签名字段如下:
1.2.1 计算body的MD5及Base64编码
<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- //以java为例
- String bodyMd5 = MD5Base64(body);
POST/PUT请求body为string 类型非空字符串:计算body的MD5,再将MD5值做Base64编码。- body为空:将bodyMd5设为””,即空字符串。
- body为REST ASR中二进制语音:需要对语音做两次MD5Base64操作,bodyMd5 = MD5Base64(MD5Base64(body))。
GET/DELETE请求
1.2.2 拼装请求验证串
<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date ;
- REST ASR接口content_type为『”audio/“+audioFormat+”;samplerate=”+sampleRate;』;
- 批量测试接口content_type为『multipart/form-data』。
1.2.3 计算Authorization
把1.2.2 中得到的stringToSign与Access Secret一起计算HMAC-SHA1后取Base64的值,然后与Access Id一起拼装为Authorization。Authorization会放在HTTP的Header中。<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- // 1.计算 HMAC-SHA1
- String signature = HMACSha1(stringToSign, ak_secret);
- // 2.得到 authorization
- String authorization = "Dataplus " + ak_id + ":" + signature;
1.3 鉴权签名范例
为了方便用户校验自己的鉴权模块是否正确,我们给出一个鉴权签名范例。我们以POST请求为例,传入一个String类型字符串”Alibaba”作为body值参与鉴权。我们设置鉴权的几个字段值如下:<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- String method = "POST";
- String accept = "application/json";
- String content_type = "application/json";
- String Date = "Wed, 31 May 2017 08:51:26 GMT";
1.3.1 计算body的MD5及Base64编码
计算”Alibaba”的MD5Base64的值为:”AsdYv2nI4ijTfKYmKX4h/Q==”。<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- public static String MD5Base64(String s) throws UnsupportedEncodingException {
- if (s == null) {
- return null;
- }
- if (s == ""){
- return "";
- }
- String encodeStr = "";
- //string 编码必须为utf-8
- byte[] utfBytes = s.getBytes("UTF-8");
- MessageDigest mdTemp;
- try {
- mdTemp = MessageDigest.getInstance("MD5");
- mdTemp.update(utfBytes);
- byte[] md5Bytes = mdTemp.digest();
- BASE64Encoder b64Encoder = new BASE64Encoder();
- encodeStr = b64Encoder.encode(md5Bytes);
- } catch (Exception e) {
- throw new Error("Failed to generate MD5 : " + e.getMessage());
- }
- return encodeStr;
- }
1.3.2 拼装请求验证串
拼装stringToSign的值为:“POST\napplication/json\nAsdYv2nI4ijTfKYmKX4h/Q==\napplication/json\nWed, 31 May 2017 08:51:26 GMT”。<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date;
1.3.3 计算Authorization
计算stringToSign和Access secret 的鉴权值为:signature = “nPuAlFx4pPPsGT55oXeigM60paw=”。<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- String signature = HMACSha1(stringToSign, ak_secret);
- public static String HMACSha1(String data, String key) {
- String result;
- try {
- SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
- Mac mac = Mac.getInstance("HmacSHA1");
- mac.init(signingKey);
- byte[] rawHmac = mac.doFinal(data.getBytes());
- result = (new BASE64Encoder()).encode(rawHmac);
- } catch (Exception e) {
- throw new Error("Failed to generate HMAC : " + e.getMessage());
- }
- return result;
- }
2. 请求与响应
2.1 请求
NLS REST服务基于标准的HTTP协议,可设置的值包含Header和Body等。
2.1.1 设置Header
- REST ASR接口content_type为『”audio/“+audioFormat+”;samplerate=”+sampleRate;』;
- 批量测试接口content_type为『multipart/form-data』。
- REST TTS接口content_type为『”audio/“+audioFormat+”;samplerate=”+sampleRate;』;
2.1.2 设置Body
根据Content-Type的不同,body的参数也各有不同:
2.2 响应
- HTTP状态200表示请求成功
- HTTP状态4XX表示客户端错误,并在body中写明具体错误码和错误消息(error_code,error_message)
- HTTP状态5XX表示服务端错误,并在body中写明具体错误码和错误消息(error_code,error_message)
- 若响应格式为JSON格式,JSON结构中会包含request_id字段,用来区分每次请求(一些老的API使用id做为请求标识)
错误消息示例<divre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- {
- "id": "be053bf9af0e406dafa8249631372d53",
- "request_id": "be053bf9af0e406dafa8249631372d53",
- "error_code": 080101,
- "error_message": "REQUEST_PARSE_ERROR(Failed to parse json object!)"
- }
为了兼容旧API,错误响应中同时包含request_id和id,值相同,后续版本会移除id字段。
2.3 参数类型和参数值类型
参数类型表示该参数出现的位置
参数值类型表示该参数的数据类型
附录 各语言编程范例
Java
<pre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- package com.alibaba.vo;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintWriter;
- import java.net.URL;
- import java.net.URLConnection;
- import java.security.MessageDigest;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Locale;
- import javax.crypto.spec.SecretKeySpec;
- import sun.misc.BASE64Encoder;
- import javax.crypto.Mac;
- @SuppressWarnings("restriction")
- public class AESDecode {
- /*
- * 计算MD5+BASE64
- */
- public static String MD5Base64(String s) {
- if (s == null)
- return null;
- String encodeStr = "";
- //编码为utf-8
- byte[] utfBytes = s.getBytes("UTF-8");
- MessageDigest mdTemp;
- try {
- mdTemp = MessageDigest.getInstance("MD5");
- mdTemp.update(utfBytes);
- byte[] md5Bytes = mdTemp.digest();
- BASE64Encoder b64Encoder = new BASE64Encoder();
- encodeStr = b64Encoder.encode(md5Bytes);
- } catch (Exception e) {
- throw new Error("Failed to generate MD5 : " + e.getMessage());
- }
- return encodeStr;
- }
- /*
- * 计算 HMAC-SHA1
- */
- public static String HMACSha1(String data, String key) {
- String result;
- try {
- SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
- Mac mac = Mac.getInstance("HmacSHA1");
- mac.init(signingKey);
- byte[] rawHmac = mac.doFinal(data.getBytes());
- result = (new BASE64Encoder()).encode(rawHmac);
- } catch (Exception e) {
- throw new Error("Failed to generate HMAC : " + e.getMessage());
- }
- return result;
- }
- /*
- * 等同于javaScript中的 new Date().toUTCString();
- */
- public static String toGMTString(Date date) {
- SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.UK);
- df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));
- return df.format(date);
- }
- /*
- * 发送POST请求
- */
- public static String sendPost(String url, String body, String ak_id, String ak_secret) throws Exception {
- PrintWriter out = null;
- BufferedReader in = null;
- String result = "";
- int statusCode = 200;
- try {
- URL realUrl = new URL(url);
- /*
- * http header 参数
- */
- String method = "POST";
- String accept = "json";
- String content_type = "application/json";
- String path = realUrl.getFile();
- String date = toGMTString(new Date());
- String bodyMd5 = "";
- // 1.对body做MD5+BASE64加密
- if(body != null && body != ""){
- bodyMd5 = MD5Base64(body);
- }
- String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date ;
- // 2.计算 HMAC-SHA1
- String signature = HMACSha1(stringToSign, ak_secret);
- // 3.得到 authorization header
- String authHeader = "Dataplus " + ak_id + ":" + signature;
- // 打开和URL之间的连接
- URLConnection conn = realUrl.openConnection();
- // 设置通用的请求属性
- conn.setRequestProperty("accept", accept);
- conn.setRequestProperty("content-type", content_type);
- conn.setRequestProperty("date", date);
- conn.setRequestProperty("Authorization", authHeader);
- // 发送POST请求必须设置如下两行
- conn.setDoOutput(true);
- conn.setDoInput(true);
- // 获取URLConnection对象对应的输出流
- out = new PrintWriter(conn.getOutputStream());
- // 发送请求参数
- out.print(body);
- // flush输出流的缓冲
- out.flush();
- // 定义BufferedReader输入流来读取URL的响应
- statusCode = ((HttpURLConnection)conn).getResponseCode();
- if(statusCode != 200) {
- in = new BufferedReader(new InputStreamReader(((HttpURLConnection)conn).getErrorStream()));
- } else {
- in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- }
- String line;
- while ((line = in.readLine()) != null) {
- result += line;
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (out != null) {
- out.close();
- }
- if (in != null) {
- in.close();
- }
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- if (statusCode != 200) {
- throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
- }
- return result;
- }
- /*
- * GET请求
- */
- public static String sendGet(String url, String ak_id, String ak_secret) throws Exception {
- String result = "";
- BufferedReader in = null;
- int statusCode = 200;
- try {
- URL realUrl = new URL(url);
- /*
- * http header 参数
- */
- String method = "GET";
- String accept = "json";
- String content_type = "application/json";
- String path = realUrl.getFile();
- String date = toGMTString(new Date());
- // 1.对body做MD5+BASE64加密
- // String bodyMd5 = MD5Base64(body);
- String stringToSign = method + "\n" + accept + "\n" + "" + "\n" + content_type + "\n" + date ;
- // 2.计算 HMAC-SHA1
- String signature = HMACSha1(stringToSign, ak_secret);
- // 3.得到 authorization header
- String authHeader = "Dataplus " + ak_id + ":" + signature;
- // 打开和URL之间的连接
- URLConnection connection = realUrl.openConnection();
- // 设置通用的请求属性
- connection.setRequestProperty("accept", accept);
- connection.setRequestProperty("content-type", content_type);
- connection.setRequestProperty("date", date);
- connection.setRequestProperty("Authorization", authHeader);
- connection.setRequestProperty("Connection", "keep-alive");
- // 建立实际的连接
- connection.connect();
- // 定义 BufferedReader输入流来读取URL的响应
- statusCode = ((HttpURLConnection)connection).getResponseCode();
- if(statusCode != 200) {
- in = new BufferedReader(new InputStreamReader(((HttpURLConnection)connection).getErrorStream()));
- } else {
- in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
- }
- String line;
- while ((line = in.readLine()) != null) {
- result += line;
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (in != null) {
- in.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- if (statusCode != 200) {
- throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
- }
- return result;
- }
- public static void main(String[] args) throws Exception {
- // 发送POST请求示例
- String ak_id1 = "NMV.............5jv"; //用户ak
- String ak_secret1 = "Fgs...............3zu"; // 用户ak_secret
- String url = "https://shujuapi.aliyun.com/org_code/service_code/api_name";
- String body = "{\"param1\": \"xxx\", \"param2\":\"xxx\"}";
- System.out.println("response body:" + sendPost(url, body, ak_id, ak_secret));
- // 发送GET请求
- String ak_id1 = "NMV.............5jv"; //用户ak
- String ak_secret1 = "Fgs...............3zu"; // 用户ak_secret
- String url1 = "https://shujuapi.aliyun.com/org_code/service_code/api_name?param1=xxx¶m2=xxx";
- System.out.println("response body:" + sendGet(url1, ak_id1, ak_secret1));
- }
- }
PHP
<pre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- <?php
- $akId = "*************";
- $akSecret = "******************";
- //更新api信息
- $url = "https://shujuapi.aliyun.com/org_code/service_code/api_name?param1=xxx¶m2=xxx";
- $options = array(
- 'http' => array(
- 'header' => array(
- 'accept'=> "application/json",
- 'content-type'=> "application/json",
- 'date'=> gmdate("D, d M Y H:i:s \G\M\T"),
- 'authorization' => ''
- ),
- 'method' => "GET", //可以是 GET, POST, DELETE, PUT
- 'content' => '' //如有数据,请用json_encode()进行编码
- )
- );
- $http = $options['http'];
- $header = $http['header'];
- $urlObj = parse_url($url);
- if(empty($urlObj["query"]))
- $path = $urlObj["path"];
- else
- $path = $urlObj["path"]."?".$urlObj["query"];
- $body = $http['content'];
- if(empty($body))
- $bodymd5 = $body;
- else
- $bodymd5 = base64_encode(md5($body,true));
- $stringToSign = $http['method']."\n".$header['accept']."\n".$bodymd5."\n".$header['content-type']."\n".$header['date'];
- $signature = base64_encode(
- hash_hmac(
- "sha1",
- $stringToSign,
- $akSecret, true));
- $authHeader = "Dataplus "."$akId".":"."$signature";
- $options['http']['header']['authorization'] = $authHeader;
- $options['http']['header'] = implode(
- array_map(
- function($key, $val){
- return $key.":".$val."\r\n";
- },
- array_keys($options['http']['header']),
- $options['http']['header']));
- $context = stream_context_create($options);
- $file = file_get_contents($url, false, $context );
- echo($file);
- ?>
Python2.7
<pre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- #!/usr/bin/python
- # -*- coding:utf-8 -*-
- from urlparse import urlparse
- import datetime
- import base64
- import hmac
- import hashlib
- import json
- import urllib2
- def get_current_date():
- date = datetime.datetime.strftime(datetime.datetime.utcnow(), "%a, %d %b %Y %H:%M:%S GMT")
- return date
- def to_md5_base64(strBody):
- hash = hashlib.md5()
- hash.update(body.encode('utf-8'))
- return hash.digest().encode('base64').strip()
- def to_sha1_base64(stringToSign, secret):
- hmacsha1 = hmac.new(secret.encode('utf-8'), stringToSign.encode('utf-8'), hashlib.sha1)
- return base64.b64encode(hmacsha1.digest()).decode('utf-8')
- ak_id = '<用户的AK_ID>'
- ak_secret = '<用户的AK_SECRET>'
- options = {
- 'url': '<请求的url>',
- 'method': 'POST',
- 'body': json.dumps({"name": "hello"}, separators=(',', ':')),
- 'headers': {
- 'accept': 'application/json',
- 'content-type': 'application/json',
- 'date': get_current_date(),
- 'authorization': ''
- }
- }
- # options = {
- # 'url': '<请求的url>',
- # 'method': 'GET',
- # 'headers': {
- # 'accept': 'application/json',
- # 'content-type': 'application/json',
- # 'date': get_current_date(), # 'Sat, 07 May 2016 08:19:52 GMT', # get_current_date(),
- # 'authorization': ''
- # }
- # }
- body = ''
- if 'body' in options:
- body = options['body']
- print body
- bodymd5 = ''
- if not body == '':
- bodymd5 = to_md5_base64(body)
- print bodymd5
- # REST ASR 接口,需要做两次鉴权
- #bodymd5 = to_md5_base64(bodymd5)
- stringToSign = options['method'] + '\n' + options['headers']['accept'] + '\n' + bodymd5 + '\n' + options['headers']['content-type'] + '\n' + options['headers']['date']
- signature = to_sha1_base64(stringToSign, ak_secret)
- print stringToSign
- authHeader = 'Dataplus ' + ak_id + ':' + signature
- options['headers']['authorization'] = authHeader
- print authHeader
- request = None
- method = options['method']
- url = options['url']
- print method
- print url
- if 'GET' == method or 'DELETE' == method:
- request = urllib2.Request(url)
- elif 'POST' == method or 'PUT' == method:
- request = urllib2.Request(url, body)
- request.get_method = lambda: method
- for key, value in options['headers'].items():
- request.add_header(key, value)
- try:
- conn = urllib2.urlopen(request)
- response = conn.read()
- print response
- except urllib2.HTTPError, e:
- print e.read()
- raise SystemExit(e)
Python 3.5
<pre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- #!/usr/bin/python
- # -*- coding:utf-8 -*-
- import hashlib
- import urllib.request
- import hmac
- import base64
- import datetime
- import ssl
- class http_proxy:
- """
- Http工具类,封装了鉴权
- """
- def __init__(self, ak_id, ak_secret):
- self.__ak_id = ak_id
- self.__ak_secret = ak_secret
- def __current_gmt_time(self):
- date = datetime.datetime.strftime(datetime.datetime.utcnow(), "%a, %d %b %Y %H:%M:%S GMT")
- return date
- def __md5_base64(self, strbody):
- hash = hashlib.md5()
- hash.update(strbody.encode('utf-8'))
- print(hash.digest())
- return base64.b64encode(hash.digest()).decode('utf-8')
- def __sha1_base64(self, str_to_sign, secret):
- hmacsha1 = hmac.new(secret.encode('utf-8'), str_to_sign.encode('utf-8'), hashlib.sha1)
- return base64.b64encode(hmacsha1.digest()).decode('utf-8')
- def send_request(self, url, body):
- gmtnow = self.__current_gmt_time()
- print(gmtnow)
- body_md5 = self.__md5_base64(body)
- print(body_md5)
- str_to_sign = "POST\napplication/json\n" + body_md5 + "\napplication/json\n" + gmtnow
- print(str_to_sign)
- signature = self.__sha1_base64(str_to_sign, self.__ak_secret)
- print(signature)
- auth_header = "Dataplus " + self.__ak_id + ":" + signature
- print(auth_header)
- ssl._create_default_https_context = ssl._create_unverified_context
- req = urllib.request.Request(url)
- req.add_header("Accept", "application/json")
- req.add_header("Content-Type", "application/json")
- req.add_header("Date", gmtnow)
- req.add_header("Authorization", auth_header)
- data = body.encode('utf-8')
- f = urllib.request.urlopen(req, data)
- return f.read().decode('utf-8')
Go
<pre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; margin: 0px 0px 16px; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- package utils
- import (
- "fmt"
- "net/http"
- "io/ioutil"
- "time"
- "bytes"
- "crypto/md5"
- "crypto/hmac"
- "crypto/sha1"
- "encoding/base64"
- )
- type HttpProxy struct {
- AkId string
- AkSecret string
- }
- func (proxy *HttpProxy)gmttime() string {
- location,_ := time.LoadLocation("GMT")
- now := time.Now().In(location)
- return now.Format("Mon, 02 Jan 2006 15:04:05 GMT")
- }
- func (proxy *HttpProxy)md5base64(strbody string) string {
- m := md5.New()
- m.Write([]byte(strbody))
- return string(base64.StdEncoding.EncodeToString(m.Sum(nil)))
- }
- func (proxy *HttpProxy)sha1base64(strToSign string, secret string) string {
- key := []byte(secret)
- h := hmac.New(sha1.New, key)
- h.Write([]byte(strToSign))
- return string(base64.StdEncoding.EncodeToString(h.Sum(nil)))
- }
- func (proxy *HttpProxy)SendRequest(url string, reqBody string) string {
- gmtnow := proxy.gmttime()
- bodyMd5 := proxy.md5base64(reqBody)
- strToSign := "POST\napplication/json\n" + bodyMd5 + "\napplication/json\n" + gmtnow;
- signature := proxy.sha1base64(strToSign, proxy.AkSecret)
- authHeader := "Dataplus " + proxy.AkId + ":" + signature
- client := &http.Client{}
- reqBodyBuf := bytes.NewBuffer([]byte(reqBody))
- request, _ := http.NewRequest("POST", url, reqBodyBuf)
- request.Header.Set("Accept", "application/json")
- request.Header.Set("Content-type", "application/json")
- request.Header.Set("Date", gmtnow)
- request.Header.Set("Authorization", authHeader)
- response, _ := client.Do(request)
- fmt.Println(response.StatusCode)
- respBody,_ := ioutil.ReadAll(response.Body)
- return string(respBody)
- }
Node.js
<pre style='background: rgb(246, 246, 246); font: 12px/1.6 "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; padding: 10px; outline: 0px; border-radius: 3px; border: 1px solid rgb(221, 221, 221); color: rgb(51, 51, 51); text-transform: none; text-indent: 0px; letter-spacing: normal; overflow: auto; margin-top: 0px; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; word-spacing: 0px; white-space: pre-wrap; word-wrap: break-word; box-sizing: border-box; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;' prettyprinted?="" linenums="">
- var request = require('request');
- var url = require('url');
- var crypto = require('crypto');
- var date = new Date().toUTCString()
- // 这里填写AK和请求
- var ak_id = 'NNV..........5jv';
- var ak_secret = 'FGs.....................3Zu';
- var options = {
- url : 'https://shujuapi.aliyun.com/org_code/service_code/api_name?param1=xxx¶m2=xxx',
- method: 'GET',
- body: '',
- headers: {
- 'accept': 'application/json',
- 'content-type': 'application/json',
- 'date': date,
- 'Authorization': ''
- }
- };
- // 这里填写AK和请求
- md5 = function(buffer) {
- var hash;
- hash = crypto.createHash('md5');
- hash.update(buffer);
- return hash.digest('base64');
- };
- sha1 = function(stringToSign, secret) {
- var signature;
- return signature = crypto.createHmac('sha1', secret).update(stringToSign).digest().toString('base64');
- };
- // step1: 组stringToSign [StringToSign = #{method}\\n#{accept}\\n#{data}\\n#{contentType}\\n#{date}]
- var body = options.body || '';
- var bodymd5;
- if(body === void 0 || body === ''){
- bodymd5 = '';
- } else {
- bodymd5 = md5(new Buffer(body));
- }
- console.log(bodymd5)
- var stringToSign = options.method + "\n" + options.headers.accept + "\n" + bodymd5 + "\n" + options.headers['content-type'] + "\n" + options.headers.date;
- console.log("step1-Sign string:", stringToSign);
- // step2: 加密 [Signature = Base64( HMAC-SHA1( AccessSecret, UTF-8-Encoding-Of(StringToSign) ) )]
- var signature = sha1(stringToSign, ak_secret);
- // console.log("step2-signature:", signature);
- // step3: 组authorization header [Authorization = Dataplus AccessKeyId + ":" + Signature]
- var authHeader = "Dataplus " + ak_id + ":" + signature;
- console.log("step3-authorization Header:", authHeader);
- options.headers.Authorization = authHeader;
- console.log('authHeader', authHeader);
- // step4: send request
- function callback(error, response, body) {
- if (error) {
- console.log("error", error)
- }
- console.log("step4-response body:", response.statusCode, body)
- }
- request(options, callback);