Topik ini menjelaskan cara mendapatkan token akses dengan memanggil operasi API.
Permintaan
Klien mengirim permintaan ke server untuk mendapatkan token akses. Server membuat token akses tersebut lalu mengembalikan tanggapan ke klien. Klien dapat menggunakan metode GET atau POST untuk mengirim permintaan HTTP atau HTTPS. Server menyediakan API Portable OpenAPI Proxy (POP), sehingga klien harus menggunakan mekanisme tanda tangan POP Alibaba Cloud untuk menambahkan tanda tangan ke setiap permintaan.
Pengaturan parameter permintaan sama untuk HTTP dan HTTPS. Topik ini menggunakan HTTP sebagai contoh untuk menjelaskan cara mengirim permintaan guna mendapatkan token akses.
URL
Protokol
URL
Metode
HTTP/1.1
http://nlsmeta.ap-southeast-1.aliyuncs.com/
GET/POST
Parameter permintaan
Parameter
Tipe
Wajib
Deskripsi
AccessKeyId
String
Ya
ID AccessKey dari akun Alibaba Cloud.
Action
String
Ya
Operasi API yang ingin Anda lakukan. Tetapkan parameter ini ke CreateToken.
Version
String
Ya
Nomor versi API POP. Tetapkan parameter ini ke 2019-02-28.
Format
String
Ya
Format tanggapan. Tetapkan parameter ini ke JSON.
RegionId
String
Ya
ID wilayah layanan. Tetapkan parameter ini ke ap-southeast-1.
Timestamp
String
Ya
Stempel waktu permintaan. Tentukan waktu dalam standar ISO 8601 dengan format yyyy-MM-ddTHH:mm:ssZ. Waktu harus dalam UTC+0. Misalnya, nilai 2019-04-03T06:15:03Z menunjukkan 06:15:03 pada 3 April 2019.
SignatureMethod
String
Ya
Algoritma tanda tangan. Tetapkan parameter ini ke HMAC-SHA1.
SignatureVersion
String
Ya
Nomor versi algoritma tanda tangan. Tetapkan parameter ini ke 1.0.
SignatureNonce
String
Ya
Bilangan acak unik yang digunakan untuk mencegah serangan replay. Anda harus menggunakan angka berbeda untuk permintaan yang berbeda. Nilainya dalam format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12). Contoh: 8d1e6a7a-f44e-40d5-aedb-fe4a1c80f434.
Signature
String
Ya
String tanda tangan yang dihitung berdasarkan semua parameter permintaan. Untuk informasi lebih lanjut tentang metode perhitungan tanda tangan, lihat bagian Mekanisme tanda tangan.
CatatanJika Anda menggunakan metode GET, tambahkan parameter permintaan ke baris permintaan dalam format berikut:
/?string parameter permintaan.Jika Anda menggunakan metode POST, tambahkan parameter permintaan ke badan permintaan.
Header permintaan HTTP
Header permintaan HTTP terdiri dari pasangan kunci-nilai. Setiap pasangan kunci-nilai merupakan satu bidang yang menempati satu baris, dengan kunci dan nilai dipisahkan oleh tanda titik dua (:). Tabel berikut menjelaskan bidang-bidang dalam header permintaan HTTP.
Parameter
Tipe
Wajib
Deskripsi
Host
String
Tidak
Titik akhir layanan Intelligent Speech Interaction yang diminta. Tetapkan bidang ini ke
nlsmeta.ap-southeast-1.aliyuncs.com. Titik akhir ini biasanya diuraikan secara otomatis berdasarkan URL permintaan.Accept
String
Tidak
Jenis konten yang dapat diterima oleh klien. Tetapkan bidang ini ke
application/json. Jika Anda tidak menentukan bidang ini, nilai default */* akan digunakan.Content-type
String
Ya untuk metode POST
Format data badan permintaan jika menggunakan metode POST. Tetapkan bidang ini ke
application/x-www-form-urlencoded.
Contoh permintaan:
Permintaan HTTP GET
GET /?Signature=O0s6pfeOxtFM6YKSZKQdSyPR9Vs%3D&AccessKeyId=LTAF3sAA****&Action=CreateToken&Format=JSON&RegionId=ap-southeast-1&SignatureMethod=HMAC-SHA1&SignatureNonce=a1f01895-6ff1-43c1-ba15-6c109fa00106&SignatureVersion=1.0&Timestamp=2019-03-27T09%3A51%3A25Z&Version=2019-02-28 HTTP/1.1 Host: nlsmeta.ap-southeast-1.aliyuncs.com User-Agent: curl/7.49.1 Accept: */*Permintaan HTTP POST
POST / HTTP/1.1 Host: nlsmeta.ap-southeast-1.aliyuncs.com User-Agent: curl/7.49.1 Accept: */* Content-type: application/x-www-form-urlencoded Content-Length: 276 SignatureVersion=1.0&Action=CreateToken&Format=JSON&SignatureNonce=8d1e6a7a-f44e-40d5-aedb-fe4a1c80f434&Version=2019-02-28&AccessKeyId=LTAF3sAA****&Signature=oT8A8RgvFE1tMD%2B3hDbGuoMQSi8%3D&SignatureMethod=HMAC-SHA1&RegionId=ap-southeast-1&Timestamp=2019-03-25T09%3A07%3A52Z
Tanggapan:
Setelah klien mengirim permintaan HTTP untuk mendapatkan token akses, server mengembalikan tanggapan. Hasilnya disimpan sebagai string JSON dalam tanggapan, yang sama untuk metode GET dan POST.
Tanggapan sukses
Kode status HTTP adalah 200. Tabel berikut menjelaskan parameter respons.
Parameter
Tipe
Deskripsi
Token
Object
Objek token yang berisi token akses dan stempel waktu yang menunjukkan periode validitas token akses.
Id
String
Token akses yang ditetapkan untuk permintaan.
ExpireTime
Long
Stempel waktu yang menunjukkan periode validitas token akses. Satuan: detik. Misalnya, nilai 1553825814 menunjukkan bahwa token akses berlaku hingga pukul 10:16:54 (UTC+8) pada 29 Maret 2019.
HTTP/1.1 200 OK Date: Mon, 25 Mar 2019 09:29:24 GMT Content-Type: application/json; charset=UTF-8 Content-Length: 216 Connection: keep-alive Access-Control-Allow-Origin: * Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-Requested-With, X-Sequence, _aop_secret, _aop_signature Access-Control-Max-Age: 172800 Server: Jetty(7.2.2.v20101205) {"NlsRequestId":"dd05a301b40441c99a2671905325****","RequestId":"E11F2DC2-0163-4D97-A704-0BD28045****","ErrMsg":"","Token":{"ExpireTime":1553592564,"Id":"88916699****","UserId":"150151111111****"}}Kode berikut menunjukkan badan respons dalam format JSON:
{ "NlsRequestId": "dd05a301b40441c99a2671905325****", "RequestId": "E11F2DC2-0163-4D97-A704-0BD28045****", "ErrMsg": "", "Token": { "ExpireTime": 1553592564, "Id": "889******166", "UserId": "150**********151" } }
Tanggapan kesalahan
Kode status HTTP bukan 200. Tabel berikut menjelaskan parameter respons.
Parameter
Tipe
Deskripsi
RequestId
String
ID permintaan.
Message
String
Pesan kesalahan dari tanggapan kesalahan.
Code
String
Kode kesalahan dari tanggapan kesalahan.
CatatanPeriksa apakah parameter permintaan telah diatur dengan benar berdasarkan kode kesalahan dan pesan kesalahan.
Contoh berikut menunjukkan tanggapan kesalahan yang disebabkan oleh ID AccessKey yang tidak valid:
HTTP/1.1 404 Not Found Date: Thu, 28 Mar 2019 07:23:01 GMT Content-Type: application/json; charset=UTF-8 Content-Length: 290 Connection: keep-alive Access-Control-Allow-Origin: * Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-Requested-With, X-Sequence, _aop_secret, _aop_signature Access-Control-Max-Age: 172800 Server: Jetty(7.2.2.v20101205) {"Recommend":"https://error-center.aliyun.com/status/search?Keyword=InvalidAccessKeyId.NotFound&source=PopGw","Message":"Specified access key is not found.","RequestId":"A51587CB-5193-4DB8-9AED-CD4365C2****","HostId":"nlsmeta.ap-southeast-1.aliyuncs.com","Code":"InvalidAccessKeyId.NotFound"}Kode berikut menunjukkan badan respons dalam format JSON:
{ "Recommend": "https://error-center.aliyun.com/status/search?Keyword=InvalidAccessKeyId.NotFound&source=PopGw", "Message": "Specified access key is not found.", "RequestId": "A51587CB-5193-4DB8-9AED-CD4365C2****", "HostId": "nlsmeta.ap-southeast-1.aliyuncs.com", "Code": "InvalidAccessKeyId.NotFound" }
Metode tanda tangan
Saat server menerima permintaan API POP, server melakukan autentikasi identitas pemanggil API. Oleh karena itu, permintaan HTTP atau HTTPS harus berisi informasi tanda tangan. Berdasarkan mekanisme tanda tangan ini, server dapat mengidentifikasi pengguna yang mengirim permintaan API dan memastikan apakah permintaan tersebut telah dimodifikasi selama transmisi jaringan.
Proses verifikasi keamanan
Intelligent Speech Interaction menggunakan algoritma HMAC-SHA1 untuk menerapkan enkripsi simetris berdasarkan ID AccessKey dan Rahasia AccessKey akun Alibaba Cloud Anda. Proses berikut menjelaskan cara memverifikasi permintaan API:
Klien menghasilkan string tanda tangan berdasarkan isi permintaan API, termasuk parameter permintaan HTTP dan badan permintaan.
Klien menggunakan ID AccessKey dan Rahasia AccessKey akun Alibaba Cloud Anda untuk mengenkripsi string tanda tangan yang dihasilkan pada Langkah 1, lalu memperoleh tanda tangan digital untuk permintaan API tersebut.
Klien mengirim permintaan API yang telah ditandatangani ke server.
Setelah menerima permintaan API, server mengulangi Langkah 1 dan 2 untuk menghitung tanda tangan digital yang diharapkan. Server memperoleh ID AccessKey dan Rahasia AccessKey yang digunakan oleh permintaan API dari Backend.
Server membandingkan tanda tangan digital yang diharapkan dengan tanda tangan digital yang dikirim oleh klien. Jika keduanya sama, permintaan lolos verifikasi keamanan; jika berbeda, server menolak permintaan API tersebut.
Hasilkan string tanda tangan untuk permintaan API
Buat string kueri yang dinormalisasi.
Buat string kueri yang dinormalisasi berdasarkan parameter permintaan HTTP, tetapi jangan sertakan parameter Signature. Untuk membuat string kueri yang dinormalisasi, lakukan langkah-langkah berikut:
Urutkan parameter permintaan secara alfabetis. Nama parameter peka huruf besar/kecil.
Enkode parameter. Normalisasi parameter permintaan yang telah diurutkan.
Enkode nama dan nilai parameter permintaan dalam
UTF-8berdasarkan aturan berikut:Huruf kapital, huruf kecil, angka, dan beberapa karakter khusus seperti tanda hubung (
-), garis bawah (_), titik (.), dan tilde (~) tidak perlu dienkode.Karakter lain harus dienkode persen dalam format %XY, di mana XY merepresentasikan kode ASCII karakter dalam notasi heksadesimal. Misalnya, tanda kutip ganda (") dienkode menjadi %22.
Karakter
UTF-8yang diperluas harus dienkode dalam format %XY%ZA….Spasi harus dienkode menjadi %20. Jangan enkode spasi sebagai tanda plus (
+).
CatatanSebagian besar pustaka yang mendukung enkode URL, seperti java.net.URLEncoder, dibuat berdasarkan aturan enkode application/x-www-form-urlencoded—sebuah subtipe Multipurpose Internet Mail Extensions (MIME). Jika Anda menggunakan metode enkode ini, gantilah tanda plus (
+) dengan%20, tanda bintang (*) dengan%2A, dan%7Edengan tilde (~) dalam string yang dienkode untuk mendapatkan string yang diperlukan.Gunakan tanda sama dengan (
=) untuk menghubungkan nama dan nilai setiap parameter permintaan yang telah dienkode URL. Contoh:percentEncode(kunci parameter) + "=" + percentEncode(nilai parameter).Gunakan tanda ampersand (
&) untuk menghubungkan pasangan kunci-nilai parameter permintaan yang telah dienkode URL yang dihasilkan pada Langkah c. Contoh:Action=CreateToken&Format=JSON.CatatanJangan tambahkan tanda ampersand (
&) sebelum nama parameter pertama dalam string kueri yang dinormalisasi.Kembalikan string kueri yang dinormalisasi.
Kode contoh:
String percentEncode(String value) throws UnsupportedEncodingException { return value != null ? URLEncoder.encode(value, URL_ENCODING) .replace("+", "%20") .replace("*", "%2A") .replace("%7E", "~") : null; } // Urutkan kunci parameter. String[] sortedKeys = queryParamsMap.keySet().toArray(new String[] {}); Arrays.sort(sortedKeys); // Enkode dan gabungkan parameter permintaan yang telah diurutkan. for (String key : sortedKeys) { canonicalizedQueryString.append("&") .append(percentEncode(key)).append("=") .append(percentEncode(queryParamsMap.get(key))); } queryString = canonicalizedQueryString.toString().substring(1);CatatanUntuk informasi lebih lanjut tentang kode contoh lengkap, lihat fungsi
canonicalizedQuerypada bagian Kode contoh lengkap.String kueri yang dinormalisasi berikut dibuat:
AccessKeyId=LTA******3s2&Action=CreateToken&Format=JSON&RegionId=ap-southeast-1&SignatureMethod=HMAC-SHA1&SignatureNonce=f20b1beb-e5dc-4245-9e96-aa582e905c1a&SignatureVersion=1.0&Timestamp=2019-04-03T03%3A40%3A13Z&Version=2019-02-28Buat string yang akan ditandatangani.
String yang akan ditandatangani terdiri dari metode permintaan HTTP, URL yang telah dienkode URL, dan string kueri yang dinormalisasi yang diperoleh pada Langkah 1. Gabungkan elemen-elemen ini menggunakan tanda ampersand (
&) dalam format berikut:HTTPMethod + "&" + percentEncode("/") + "&" + percentEncode(queryString).Kode contoh berikut memberikan contoh cara membuat string yang akan ditandatangani:
StringBuilder strBuilderSign = new StringBuilder(); strBuilderSign.append(HTTPMethod); strBuilderSign.append("&"); strBuilderSign.append(percentEncode(urlPath)); strBuilderSign.append("&"); strBuilderSign.append(percentEncode(queryString)); stringToSign = strBuilderSign.toString();CatatanUntuk informasi lebih lanjut tentang kode contoh lengkap, lihat fungsi
createStringToSignpada bagian Kode contoh lengkap.String yang akan ditandatangani berikut dibuat:

Hitung tanda tangan.
Gunakan algoritma HMAC-SHA1 dan Base64 untuk menghitung nilai HMAC dari string yang akan ditandatangani, lalu enkode nilai HMAC tersebut dalam
UTF-8.Gunakan algoritma SHA1 untuk menghitung nilai HMAC dari string yang akan ditandatangani yang dibuat pada Langkah 2, dengan Rahasia AccessKey sebagai kunci perhitungan HMAC. Tambahkan tanda ampersand (
&) setelah Rahasia AccessKey.Lakukan enkode URL untuk tanda tangan yang dihitung.
Kode contoh berikut memberikan contoh cara menghitung tanda tangan:
signature = Base64( HMAC-SHA1(stringToSign, accessKeySecret + "&") ); // Lakukan enkode URL signature = percentEncode(signature)CatatanUntuk informasi lebih lanjut tentang kode contoh lengkap, lihat fungsi
signpada bagian Kode contoh lengkap.Tanda tangan berikut dihitung:
# Nilai HMAC dari string yang akan ditandatangani AKIktdPUMCV12fTh667BLXeuCtg= # Tanda tangan yang telah dienkode URL AKIktdPUMCV12fTh667BLXeuCtg%3DSetelah tanda tangan dihitung, gunakan tanda sama dengan (
=) untuk menghubungkan kunci dan nilai parameter Signature. Kemudian, gunakan tanda ampersand (&) untuk menghubungkan parameter Signature dengan string kueri yang dinormalisasi yang diperoleh pada Langkah 1. Dengan demikian, klien dapat mengirim permintaan HTTP GET yang telah ditandatangani ke server untuk mendapatkan token akses.String queryStringWithSign = "Signature=" + signature + "&" + queryString;
Pengujian cepat
Gunakan parameter berikut untuk menghitung tanda tangan dan menguji tanda tangan yang dihitung.
ID AccessKey dan Rahasia AccessKey tidak asli. Stempel waktu telah kedaluwarsa. Anda tidak dapat memperoleh token akses dengan menggunakan tanda tangan yang dihitung berdasarkan parameter ini. Parameter ini hanya digunakan untuk menghitung dan menguji tanda tangan.
AccessKeyId:
my_access_key_idAccessKeySecret:
my_access_key_secretTimestamp:
2019-04-18T08:32:31ZSignatureNonce:
b924c8c3-6d03-4c5d-ad36-d984d3116788
Parameter permintaan berikut digunakan:
AccessKeyId:my_access_key_id
Action:CreateToken
Version:2019-02-28
Timestamp:2019-04-18T08:32:31Z
Format:JSON
RegionId:ap-southeast-1
SignatureMethod:HMAC-SHA1
SignatureVersion:1.0
SignatureNonce:b924c8c3-6d03-4c5d-ad36-d984d3116788Buat string kueri yang dinormalisasi.
AccessKeyId=my_access_key_id&Action=CreateToken&Format=JSON&RegionId=ap-southeast-1&SignatureMethod=HMAC-SHA1&SignatureNonce=b924c8c3-6d03-4c5d-ad36-d984d3116788&SignatureVersion=1.0&Timestamp=2019-04-18T08%3A32%3A31Z&Version=2019-02-28Buat string yang akan ditandatangani.

Hitung dan peroleh tanda tangan.
hHq4yNsPitlfDJ2L0nQPdugdEzM= # Tanda tangan yang telah dienkode URL hHq4yNsPitlfDJ2L0nQPdugdEzM%3DTambahkan tanda tangan ke string kueri yang dinormalisasi.
Signature=hHq4yNsPitlfDJ2L0nQPdugdEzM%3D&AccessKeyId=my_access_key_id&Action=CreateToken&Format=JSON&RegionId=ap-southeast-1&SignatureMethod=HMAC-SHA1&SignatureNonce=b924c8c3-6d03-4c5d-ad36-d984d3116788&SignatureVersion=1.0&Timestamp=2019-04-18T08%3A32%3A31Z&Version=2019-02-28Peroleh URL permintaan HTTP.
http://nlsmeta.ap-southeast-1.aliyuncs.com/?Signature=hHq4yNsPitlfDJ2L0nQPdugdEzM%3D&AccessKeyId=my_access_key_id&Action=CreateToken&Format=JSON&RegionId=ap-southeast-1&SignatureMethod=HMAC-SHA1&SignatureNonce=b924c8c3-6d03-4c5d-ad36-d984d3116788&SignatureVersion=1.0&Timestamp=2019-04-18T08%3A32%3A31Z&Version=2019-02-28Masukkan URL permintaan HTTP yang diperoleh pada Langkah 5 ke bilah alamat browser Anda atau jalankan perintah curl berikut untuk mendapatkan token akses.
curl "http://nlsmeta.ap-southeast-1.aliyuncs.com/?Signature=${Your signature}&AccessKeyId=${Your AccessKey ID}&Action=CreateToken&Format=JSON&RegionId=ap-southeast-1&SignatureMethod=HMAC-SHA1&SignatureNonce=${Your request UUID}&SignatureVersion=1.0&Timestamp=${Your request timestamp}&Version=2019-02-28"
Kode contoh lengkap
Bagian ini menyediakan kode contoh untuk Java dan Python. Anda dapat menulis kode untuk program klien dalam bahasa lain berdasarkan protokol dan kode contoh ini.
Demo untuk Java
Tambahkan dependensi berikut:
<!-- http://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.9.1</version> </dependency>Kode contoh:
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.SimpleTimeZone; import java.util.UUID; public class CreateToken { private final static String TIME_ZONE = "GMT"; private final static String FORMAT_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'"; private final static String URL_ENCODING = "UTF-8"; private static final String ALGORITHM_NAME = "HmacSHA1"; private static final String ENCODING = "UTF-8"; private static String token = null; private static long expireTime = 0; /** * Obtain the timestamp. * Specify the time in the ISO 8601 standard in the yyyy-MM-ddTHH:mm:ssZ format. The time must be in UTC+0. */ public static String getISO8601Time(Date date) { Date nowDate = date; if (null == date) { nowDate = new Date(); } SimpleDateFormat df = new SimpleDateFormat(FORMAT_ISO8601); df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE)); return df.format(nowDate); } /** * Obtain the UUID of the request. */ public static String getUniqueNonce() { UUID uuid = UUID.randomUUID(); return uuid.toString(); } /** * Perform URL encoding. * Use UTF-8 to encode the names and values of the request parameters based on RFC 3986. */ public static String percentEncode(String value) throws UnsupportedEncodingException { return value != null ? URLEncoder.encode(value, URL_ENCODING).replace("+", "%20") .replace("*", "%2A").replace("%7E", "~") : null; } /*** * Sort the request parameters and concatenate the sorted request parameters to create a canonicalized query string. * @param queryParamsMap All request parameters. * @return The canonicalized query string. */ public static String canonicalizedQuery( Map<String, String> queryParamsMap) { String[] sortedKeys = queryParamsMap.keySet().toArray(new String[] {}); Arrays.sort(sortedKeys); String queryString = null; try { StringBuilder canonicalizedQueryString = new StringBuilder(); for (String key : sortedKeys) { canonicalizedQueryString.append("&") .append(percentEncode(key)).append("=") .append(percentEncode(queryParamsMap.get(key))); } queryString = canonicalizedQueryString.toString().substring(1); System.out.println("Canonicalized query string: " + queryString); } catch (UnsupportedEncodingException e) { System.out.println("UTF-8 encoding is not supported."); e.printStackTrace(); } return queryString; } /*** * Create a string-to-sign. * @param method The HTTP request method. * @param urlPath The HTTP request URL. * @param queryString The canonicalized query string. * @return The string-to-sign. */ public static String createStringToSign(String method, String urlPath, String queryString) { String stringToSign = null; try { StringBuilder strBuilderSign = new StringBuilder(); strBuilderSign.append(method); strBuilderSign.append("&"); strBuilderSign.append(percentEncode(urlPath)); strBuilderSign.append("&"); strBuilderSign.append(percentEncode(queryString)); stringToSign = strBuilderSign.toString(); System.out.println("string-to-sign: " + stringToSign); } catch (UnsupportedEncodingException e) { System.out.println("UTF-8 encoding is not supported."); e.printStackTrace(); } return stringToSign; } /*** * Calculate the signature. * @param stringToSign The string-to-sign. * @param accessKeySecret The AccessKey secret that is appended with an ampersand (&). * @return The calculated signature. */ public static String sign(String stringToSign, String accessKeySecret) { try { Mac mac = Mac.getInstance(ALGORITHM_NAME); mac.init(new SecretKeySpec( accessKeySecret.getBytes(ENCODING), ALGORITHM_NAME )); byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING)); String signBase64 = DatatypeConverter.printBase64Binary(signData); System.out.println("Calculated signature: " + signBase64); String signUrlEncode = percentEncode(signBase64); System.out.println("URL encoded signature: " + signUrlEncode); return signUrlEncode; } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException(e.toString()); } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e.toString()); } catch (InvalidKeyException e) { throw new IllegalArgumentException(e.toString()); } } /*** * Send an HTTP GET request to obtain an access token and the timestamp that indicates the validity period of the access token. * @param queryString The request parameters. */ public static void processGETRequest(String queryString) { /** * Create an HTTP GET request. * 1. Use HTTP. * 2. Use the endpoint of Intelligent Speech Interaction: nlsmeta.ap-southeast-1.aliyuncs.com * 3. Request URL: / * 4. Set the request parameters. */ String url = "http://nlsmeta.ap-southeast-1.aliyuncs.com"; url = url + "/"; url = url + "?" + queryString; System.out.println("HTTP request URL: " + url); Request request = new Request.Builder() .url(url) .header("Accept", "application/json") .get() .build(); try { OkHttpClient client = new OkHttpClient(); Response response = client.newCall(request).execute(); String result = response.body().string(); if (response.isSuccessful()) { JSONObject rootObj = JSON.parseObject(result); JSONObject tokenObj = rootObj.getJSONObject("Token"); if (tokenObj != null) { token = tokenObj.getString("Id"); expireTime = tokenObj.getLongValue("ExpireTime"); } else{ System.err.println("Failed to send the request to obtain an access token: " + result); } } else { System.err.println("Failed to send the request to obtain an access token: " + result); } response.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String args[]) { if (args.length < 2) { System.err.println("CreateTokenDemo need params: <AccessKey Id> <AccessKey Secret>"); System.exit(-1); } String accessKeyId = args[0]; String accessKeySecret = args[1]; System.out.println(getISO8601Time(null)); // All request parameters. Map<String, String> queryParamsMap = new HashMap<String, String>(); queryParamsMap.put("AccessKeyId", accessKeyId); queryParamsMap.put("Action", "CreateToken"); queryParamsMap.put("Version", "2019-02-28"); queryParamsMap.put("Timestamp", getISO8601Time(null)); queryParamsMap.put("Format", "JSON"); queryParamsMap.put("RegionId", "ap-southeast-1"); queryParamsMap.put("SignatureMethod", "HMAC-SHA1"); queryParamsMap.put("SignatureVersion", "1.0"); queryParamsMap.put("SignatureNonce", getUniqueNonce()); /** * 1. Create a canonicalized query string. */ String queryString = canonicalizedQuery(queryParamsMap); if (null == queryString) { System.out.println("Failed to create the canonicalized query string."); return; } /** * 2. Create a string-to-sign. */ String method = "GET"; // The HTTP request method, such as GET. String urlPath = "/"; // The HTTP request URL. String stringToSign = createStringToSign(method, urlPath, queryString); if (null == stringToSign) { System.out.println("Failed to create the string-to-sign."); return; } /** * 3. Calculate the signature. */ String signature = sign(stringToSign, accessKeySecret + "&"); if (null == signature) { System.out.println("Failed to calculate the signature.") return; } /** * 4. Add the signature to the canonicalized query string that is obtained in Step 1. */ String queryStringWithSign = "Signature=" + signature + "&" + queryString; System.out.println("Query string that contains the signature: " + queryStringWithSign); /** * 5. Send the HTTP GET request to obtain an access token. */ processGETRequest(queryStringWithSign); if (token != null) { System.out.println("Obtained token: " + token + ", Timestamp of the validity period (unit: seconds): "+ expireTime); // Convert the 10-digit timestamp to a time in UTC+8. String expireDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(expireTime * 1000)); System.out.println("Validity period of the access token in UTC+8: " + expireDate); } } }Demo untuk Python
CatatanVersi Python harus Python 3.4 atau yang lebih baru.
Jalankan perintah berikut untuk menginstal pustaka HTTP Python Requests:
pip install requests
#!/usr/bin/env python # -*- coding: utf-8 -*- import base64 import hashlib import hmac import requests import time import uuid from urllib import parse class AccessToken: @staticmethod def _encode_text(text): encoded_text = parse.quote_plus(text) return encoded_text.replace('+', '%20').replace('*', '%2A').replace('%7E', '~') @staticmethod def _encode_dict(dic): keys = dic.keys() dic_sorted = [(key, dic[key]) for key in sorted(keys)] encoded_text = parse.urlencode(dic_sorted) return encoded_text.replace('+', '%20').replace('*', '%2A').replace('%7E', '~') @staticmethod def create_token(access_key_id, access_key_secret): parameters = {'AccessKeyId': access_key_id, 'Action': 'CreateToken', 'Format': 'JSON', 'RegionId': 'ap-southeast-1', 'SignatureMethod': 'HMAC-SHA1', 'SignatureNonce': str(uuid.uuid1()), 'SignatureVersion': '1.0', 'Timestamp': time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), 'Version': '2019-02-28'} # Create a canonicalized query string. query_string = AccessToken._encode_dict(parameters) print('Canonicalized query string: %s' % query_string) # Create a string-to-sign. string_to_sign = 'GET' + '&' + AccessToken._encode_text('/') + '&' + AccessToken._encode_text(query_string) print('string-to-sign: %s' % string_to_sign) # Calculate the signature. secreted_string = hmac.new(bytes(access_key_secret + '&', encoding='utf-8'), bytes(string_to_sign, encoding='utf-8'), hashlib.sha1).digest() signature = base64.b64encode(secreted_string) print('Signature: %s' % signature) // Encode the calculated signature. signature = AccessToken._encode_text(signature) print('URL encoded signature: %s' % signature) # Create an HTTP GET request. full_url = 'http://nlsmeta.ap-southeast-1.aliyuncs.com/?Signature=%s&%s' % (signature, query_string) print('url: %s' % full_url) # Send the HTTP GET request. response = requests.get(full_url) if response.ok: root_obj = response.json() key = 'Token' if key in root_obj: token = root_obj[key]['Id'] expire_time = root_obj[key]['ExpireTime'] return token, expire_time print(response.text) return None, None if __name__ == "__main__": # The user information. access_key_id = 'Your AccessKey ID' access_key_secret = 'Your AccessKey secret' token, expire_time = AccessToken.create_token(access_key_id, access_key_secret) print('token: %s, expire time(s): %s' % (token, expire_time)) if expire_time: print('Validity period of the token in UTC+8: %s' % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(expire_time))))