All Products
Search
Document Center

:Obtain an access token by calling an API operation

Last Updated:Jun 11, 2024

This topic describes how to obtain an access token by calling an API operation.

Request

The client sends a request to the server to obtain an access token. The server creates an access token and then returns a response to the client. The client can use the GET or POST method to send HTTP or HTTPS requests. The server provides the Portable OpenAPI Proxy (POP) API. Therefore, the client must use the Alibaba Cloud POP signature mechanism to add a signature to each request.

Request parameter settings are the same for HTTP and HTTPS. This topic uses HTTP as an example to describe how to send a request to obtain an access token.

  • URL

    Protocol

    URL

    Method

    HTTP/1.1

    http://nlsmeta.ap-southeast-1.aliyuncs.com/

    GET/POST

  • Request parameters

    Parameter

    Type

    Required

    Description

    AccessKeyId

    String

    Yes

    The AccessKey ID of the Alibaba Cloud account.

    Action

    String

    Yes

    The API operation that you want to perform. Set this parameter to CreateToken.

    Version

    String

    Yes

    The version number of the POP API. Set this parameter to 2019-02-28.

    Format

    String

    Yes

    The format of the response. Set this parameter to JSON.

    RegionId

    String

    Yes

    The region ID of the service. Set this parameter to ap-southeast-1.

    Timestamp

    String

    Yes

    The timestamp of the request. Specify the time in the ISO 8601 standard in the yyyy-MM-ddTHH:mm:ssZ format. The time must be in UTC+0. For example, a value of 2019-04-03T06:15:03Z specifies 06:15:03 on April 3, 2019.

    SignatureMethod

    String

    Yes

    The signature algorithm. Set this parameter to HMAC-SHA1.

    SignatureVersion

    String

    Yes

    The version number of the signature algorithm. Set this parameter to 1.0.

    SignatureNonce

    String

    Yes

    A unique random number that is used to prevent replay attacks. You must use different numbers for different requests. The value is in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12) format. Example: 8d1e6a7a-f44e-40d5-aedb-fe4a1c80f434.

    Signature

    String

    Yes

    The signature string that is calculated based on all request parameters. For more information about the signature calculation method, see the Signature mechanism section.

    Note

    • If you use the GET method, you must add the request parameters to the request line in the following format: /?request parameter string.

    • If you use the POST method, you must add the request parameters to the request body.

  • HTTP request header

    The HTTP request header consists of key-value pairs. Each key-value pair is a field that occupies a line. The key and the value in each pair are separated with a colon (:). The following table describes the fields of the HTTP request header.

    Parameter

    Type

    Required

    Description

    Host

    String

    No

    The endpoint of the requested Intelligent Speech Interaction service. Set this field to nlsmeta.ap-southeast-1.aliyuncs.com. This endpoint is usually automatically resolved based on the request URL.

    Accept

    String

    No

    The type of content that the client can receive. Set this field to application/json. If you do not specify this field, the default value */* is used.

    Content-type

    String

    Yes for the POST method

    The data format of the request body if the POST method is used. Set this field to application/x-www-form-urlencoded.

Sample requests:

  • HTTP GET request

    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: */*
  • HTTP POST request

    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

Responses:

After the client sends an HTTP request to obtain an access token, the server returns a response. The result is stored as a JSON string in the response. The response is the same for the GET and POST methods.

  • Success response

    The HTTP status code is 200. The following table describes the response parameters.

    Parameter

    Type

    Description

    Token

    Object

    The token object that contains the access token and the timestamp that indicates the validity period of the access token.

    Id

    String

    The access token that is assigned to the request.

    ExpireTime

    Long

    The timestamp that indicates the validity period of the access token. Unit: seconds. For example, a value of 1553825814 indicates that the access token is valid before 10:16:54 (UTC+8) on March 29, 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****"}}

    The following code shows the response body in the JSON format:

    {
        "NlsRequestId": "dd05a301b40441c99a2671905325****",
        "RequestId": "E11F2DC2-0163-4D97-A704-0BD28045****",
        "ErrMsg": "",
        "Token": {
            "ExpireTime": 1553592564,
            "Id": "889******166",
            "UserId": "150**********151"
        }
    }

  • Error response

    The HTTP status code is not 200. The following table describes the response parameters.

    Parameter

    Type

    Description

    RequestId

    String

    The ID of the request.

    Message

    String

    The error message of the error response.

    Code

    String

    The error code of the error response.

    Note

    Check whether the request parameters are properly set based on the error code and the error message.

    The following example shows an error response that is caused by an invalid AccessKey ID:

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

    The following code shows the response body in the JSON format:

    {
        "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"
    }

Signature method

When the server receives a POP API request, it authenticates the identity of the API caller. Therefore, the HTTP or HTTPS request must contain signature information. Based on the signature mechanism, the server can identify the user that sends the API request and confirm whether the API request is tampered with during network transmission.

Security verification process

Intelligent Speech Interaction uses the HMAC-SHA1 algorithm to implement symmetric encryption based on the AccessKey ID and the AccessKey secret of your Alibaba Cloud account. The following process shows how to verify an API request:

  1. The client generates a string signature based on the content of an API request that includes the HTTP request parameters and the request body.

  2. The client uses the AccessKey ID and the AccessKey secret of your Alibaba Cloud account to encrypt the signature string that is generated in Step 1. Then, the client obtains a digital signature for this API request.

  3. The client sends the signed API request to the server.

  4. After the server receives the API request, it repeats Steps 1 and 2 to calculate the expected digital signature for the API request. The server can obtain the AccessKey ID and the AccessKey secret that are used by the API request from the backend.

  5. The server compares the expected digital signature with the digital signature that is sent from the client. If the signatures are the same, the request passes the security verification. If the signatures are different, the server rejects the API request.

Generate a signature string for an API request

  1. Create a canonicalized query string.

    Create a canonicalized query string based on the HTTP request parameters but do not include the Signature parameter. To create a canonicalized query string, perform the following steps:

    1. Sort the request parameters in alphabetical order. Parameter names are case-sensitive.

    2. Encode the parameters. Canonicalize the sorted request parameters.

      Encode the names and values of the request parameters in UTF-8 based on the following rules:

      • Uppercase letters, lowercase letters, digits, and some special characters such as hyphens (-), underscores (_), periods (.), and tildes (~) do not need to be encoded.

      • Other characters must be percent encoded in the %XY format. XY represents the ASCII code of the characters in hexadecimal notation. For example, double quotation marks (") are encoded as %22.

      • Extended UTF-8 characters must be encoded in the %XY%ZA… format.

      • Spaces must be encoded as %20. Do not encode spaces as plus signs (+).

      Note

      Most libraries that support URL encoding, such as java.net.URLEncoder, are created based on the encoding rules of application/x-www-form-urlencoded. application/x-www-form-urlencoded is a subtype of Multipurpose Internet Mail Extensions (MIME). If you use this encoding method, you can replace a plus sign (+) with %20, an asterisk (*) with %2A, and %7E with a tilde (~) in the encoded string to obtain the required string.

    3. Use an equal sign (=) to connect the name and the value of each URL encoded request parameter. Example: percentEncode (parameter key) + "=" + percentEncode (parameter value).

    4. Use an ampersand (&) to connect the key-value pairs of the URL encoded request parameters that are generated in Step c. Example: Action=CreateToken&Format=JSON.

      Note

      Do not add an ampersand (&) before the first parameter name of the canonicalized query string.

    5. Return the canonicalized query string.

    Sample code:

    String percentEncode(String value) throws UnsupportedEncodingException {
        return value != null ? URLEncoder.encode(value, URL_ENCODING)
                .replace("+", "%20")
                .replace("*", "%2A")
                .replace("%7E", "~") : null;
    }
    
    // Sort the parameter keys.
    String[] sortedKeys = queryParamsMap.keySet().toArray(new String[] {});
    Arrays.sort(sortedKeys);
    
    // Encode and concatenate the sorted request parameters.
    for (String key : sortedKeys) {
        canonicalizedQueryString.append("&")
                .append(percentEncode(key)).append("=")
                .append(percentEncode(queryParamsMap.get(key)));
    }
    queryString = canonicalizedQueryString.toString().substring(1);
    Note

    For more information about the complete sample code, see the canonicalizedQuery function in the Complete sample code section.

    The following canonicalized query string is created:

    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. Create a string-to-sign.

    A string-to-sign consists of the HTTP request method, the URL encoded URL, and the URL encoded canonicalized query string that is obtained in Step 1. Use ampersands (&) to concatenate these elements in the following format: HTTPMethod + "&" + percentEncode("/") + "&" + percentEncode(queryString).

    The following sample code provides an example to show how to create a string-to-sign:

    StringBuilder strBuilderSign = new StringBuilder();
    strBuilderSign.append(HTTPMethod);
    strBuilderSign.append("&");
    strBuilderSign.append(percentEncode(urlPath));
    strBuilderSign.append("&");
    strBuilderSign.append(percentEncode(queryString));
    
    stringToSign = strBuilderSign.toString();
    Note

    For more information about the complete sample code, see the createStringToSign function in the Complete sample code section.

    The following string-to-sign is created:

    String-to-sign

  3. Calculate the signature.

    • Use the HMAC-SHA1 algorithm and Base64 to calculate the HMAC value of the string-to-sign. Then, encode the calculated HMAC value in UTF-8.

    • Use the SHA1 algorithm to calculate the HMAC value of the string-to-sign that is created in Step 2. The AccessKey secret is used as the key for the HMAC calculation. You must add an ampersand (&) after the AccessKey secret.

    • Perform URL encoding for the calculated signature.

    The following sample code provides an example to show how to calculate the signature:

    signature = Base64( HMAC-SHA1(stringToSign, accessKeySecret + "&") );
    // Perform URL encoding
    signature = percentEncode(signature)
    Note

    For more information about the complete sample code, see the sign function in the Complete sample code section.

    The following signature is calculated:

    # The HMAC value of the string-to-sign
    AKIktdPUMCV12fTh667BLXeuCtg=
    # The URL encoded signature
    AKIktdPUMCV12fTh667BLXeuCtg%3D

    After the signature is calculated, use an equal sign (=) to connect the key and the value of the Signature parameter. Then, use an ampersand (&) to connect the Signature parameter and the canonicalized query string that is obtained in Step 1. Then, the client can send the signed HTTP GET request to the server to obtain an access token.

    String queryStringWithSign = "Signature=" + signature + "&" + queryString;

Quick test

Use the following parameters to calculate a signature and test the calculated signature.

Note

The AccessKey ID and the AccessKey secret are not real. The timestamp has expired. You cannot obtain an access token by using the signature that is calculated based on these parameters. These parameters are used only to calculate and test a signature.

  • AccessKeyId: 

    my_access_key_id

  • AccessKeySecret: 

    my_access_key_secret

  • Timestamp: 

    2019-04-18T08:32:31Z

  • SignatureNonce: 

    b924c8c3-6d03-4c5d-ad36-d984d3116788

The following request parameters are used:

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. Create a canonicalized query string.

    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. Create a string-to-sign.

    String-to-sign

  3. Calculate and obtain the signature.

    hHq4yNsPitlfDJ2L0nQPdugdEzM=
    # The URL encoded signature
    hHq4yNsPitlfDJ2L0nQPdugdEzM%3D

  4. Add the signature to the canonicalized query string.

    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. Obtain the HTTP request URL.

    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. Enter the HTTP request URL that is obtained in Step 5 in the address bar of your browser or run the following curl command to obtain an access token.

    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"

Complete sample code

Note

This section provides the sample code for Java and Python. You can write the code for client programs in other languages based on these protocols and sample code.

  • Demo for Java

    Add the following dependency:

    <!-- 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>

    Sample code:

    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 for Python

    Note

    • The Python version must be Python 3.4 or later.

    • Run the following command to install the Python HTTP library 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))))