All Products
Search
Document Center

:Mendapatkan token akses dengan memanggil operasi API

Last Updated:Nov 11, 2025

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.

    Catatan

    • Jika 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.

    Catatan

    Periksa 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:

  1. Klien menghasilkan string tanda tangan berdasarkan isi permintaan API, termasuk parameter permintaan HTTP dan badan permintaan.

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

  3. Klien mengirim permintaan API yang telah ditandatangani ke server.

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

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

  1. 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:

    1. Urutkan parameter permintaan secara alfabetis. Nama parameter peka huruf besar/kecil.

    2. Enkode parameter. Normalisasi parameter permintaan yang telah diurutkan.

      Enkode nama dan nilai parameter permintaan dalam UTF-8 berdasarkan 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-8 yang diperluas harus dienkode dalam format %XY%ZA….

      • Spasi harus dienkode menjadi %20. Jangan enkode spasi sebagai tanda plus (+).

      Catatan

      Sebagian 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 %7E dengan tilde (~) dalam string yang dienkode untuk mendapatkan string yang diperlukan.

    3. Gunakan tanda sama dengan (=) untuk menghubungkan nama dan nilai setiap parameter permintaan yang telah dienkode URL. Contoh: percentEncode(kunci parameter) + "=" + percentEncode(nilai parameter).

    4. Gunakan tanda ampersand (&) untuk menghubungkan pasangan kunci-nilai parameter permintaan yang telah dienkode URL yang dihasilkan pada Langkah c. Contoh: Action=CreateToken&Format=JSON.

      Catatan

      Jangan tambahkan tanda ampersand (&) sebelum nama parameter pertama dalam string kueri yang dinormalisasi.

    5. 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);
    Catatan

    Untuk informasi lebih lanjut tentang kode contoh lengkap, lihat fungsi canonicalizedQuery pada 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-28

  2. Buat 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();
    Catatan

    Untuk informasi lebih lanjut tentang kode contoh lengkap, lihat fungsi createStringToSign pada bagian Kode contoh lengkap.

    String yang akan ditandatangani berikut dibuat:

    String-to-sign

  3. 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)
    Catatan

    Untuk informasi lebih lanjut tentang kode contoh lengkap, lihat fungsi sign pada bagian Kode contoh lengkap.

    Tanda tangan berikut dihitung:

    # Nilai HMAC dari string yang akan ditandatangani
    AKIktdPUMCV12fTh667BLXeuCtg=
    # Tanda tangan yang telah dienkode URL
    AKIktdPUMCV12fTh667BLXeuCtg%3D

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

Catatan

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_id

  • AccessKeySecret:

    my_access_key_secret

  • Timestamp:

    2019-04-18T08:32:31Z

  • SignatureNonce:

    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-d984d3116788
  1. Buat 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-28

  2. Buat string yang akan ditandatangani.

    String-to-sign

  3. Hitung dan peroleh tanda tangan.

    hHq4yNsPitlfDJ2L0nQPdugdEzM=
    # Tanda tangan yang telah dienkode URL
    hHq4yNsPitlfDJ2L0nQPdugdEzM%3D

  4. Tambahkan 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-28

  5. Peroleh 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-28

  6. Masukkan 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

Catatan

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

    Catatan

    • Versi 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))))