Obtain a token using OpenAPI

更新时间:
复制 MD 格式

To obtain a token using OpenAPI, you must write code for identity verification and request logic. You can use this method if an SDK is not available for your programming language or if you want to control dependent components. This topic describes how to obtain a token using OpenAPI.

Request message

A client sends a request to the server to obtain a token. The server then returns a response that contains the result of the token creation. The client can send requests over HTTP or HTTPS using the GET or POST method. The server provides an API based on the Alibaba Cloud Portable OpenAPI Proxy (POP) protocol. Therefore, the client must implement the Alibaba Cloud POP signature mechanism.

Because the request parameter settings are the same for HTTP and HTTPS, this topic uses an HTTP request as an example.

  • URL

    Protocol

    URL

    Method

    HTTP/1.1

    http://nls-meta.cn-shanghai.aliyuncs.com/

    GET/POST

  • Request parameters

    Name

    Type

    Required

    Description

    AccessKeyId

    String

    Yes

    The AccessKey ID of your Alibaba Cloud account.

    Action

    String

    Yes

    The name of the POP API operation: CreateToken

    Version

    String

    Yes

    The version of the POP API: 2019-02-28

    Format

    String

    Yes

    The format of the response: JSON

    RegionId

    String

    Yes

    The ID of the region where the service is deployed: cn-shanghai

    Timestamp

    String

    Yes

    The timestamp of the request. The time must be in UTC and follow the ISO 8601 standard. Use the YYYY-MM-DDThh:mm:ssZ format. For example, 2019-04-03T06:15:03Z is 06:15:03 on April 3, 2019 (UTC).

    SignatureMethod

    String

    Yes

    The signature algorithm: HMAC-SHA1

    SignatureVersion

    String

    Yes

    The version of the signature algorithm: 1.0

    SignatureNonce

    String

    Yes

    A unique random number (UUID) to prevent replay attacks. Each request must have a unique UUID. The format is A-B-C-D-E, where the character counts are 8-4-4-4-12. For example, 8d1e6a7a-f44e-40d5-aedb-fe4a1c80f434.

    Signature

    String

    Yes

    The signature string that is calculated based on all request parameters. For information about how to generate the signature, see the "Signature mechanism" section.

    Note

    • If you use the GET method, add the request parameters to the request line: /?request_parameter_string.

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

  • HTTP request header

    The HTTP request header consists of key-value pairs. Each pair is on a separate line, and the key and value are separated by a colon (:). The following table describes the header fields.

    Name

    Type

    Required

    Description

    Host

    String

    No

    The domain name of the server that receives the HTTP request: nls-meta.cn-shanghai.aliyuncs.com. This is typically parsed automatically from the request URL.

    Accept

    String

    No

    The content type that the client can accept: application/json. If you do not set this parameter, the default value */* is used.

    Content-type

    String

    Required for the POST method

    The data format of the request body for a POST request: application/x-www-form-urlencoded.

Sample messages:

  • HTTP GET request message

    GET /?Signature=O0s6pfeOxtFM6YKSZKQdSyPR9Vs%3D&AccessKeyId=LTAF3sAA****&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&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: nls-meta.cn-shanghai.aliyuncs.com
    User-Agent: curl/7.49.1
    Accept: */*
  • HTTP POST request message

    POST / HTTP/1.1
    Host: nls-meta.cn-shanghai.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=cn-shanghai&Timestamp=2019-03-25T09%3A07%3A52Z

Response result:

After you send an HTTP request to obtain a token, the server returns a response. The result is a JSON string in the response body. The response is the same for both GET and POST methods.

  • Successful response

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

    Parameter

    Type

    Description

    Token

    Token object

    Contains the token value and its expiration timestamp.

    Id

    String

    The token value assigned to the request.

    ExpireTime

    Long

    The expiration timestamp of the token, in seconds. For example, the UNIX timestamp 1553825814 corresponds to 10:16:54 on March 29, 2019 (UTC+8). The token is valid before this time.

    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 content of the response body, which is a JSON string.

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

    An HTTP status code other than 200 is returned. The following table describes the response fields.

    Parameter

    Type

    Description

    RequestId

    String

    The request ID.

    Message

    String

    The error message returned for the failed response.

    Code

    String

    The error code returned for the failed response.

    Note

    Use the error code and error message to check if the request parameters are set correctly.

    The following response message is an example of an error caused by an incorrect 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":"nls-meta.cn-shanghai.aliyuncs.com","Code":"InvalidAccessKeyId.NotFound"}

    The response body contains the following JSON string.

    {
        "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": "nls-meta.cn-shanghai.aliyuncs.com",
        "Code": "InvalidAccessKeyId.NotFound"
    }

Signature mechanism

The server authenticates the sender of each POP API request. Therefore, you must include signature information in each HTTP or HTTPS request. The signature mechanism allows the server to identify the user who sends a request and verify that the request has not been tampered with during transmission.

Security verification process:

To calculate a signature, you need the AccessKey ID and AccessKey secret from your Alibaba Cloud account. The HMAC-SHA1 algorithm is used for symmetric encryption. The workflow is as follows.

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

  2. The client uses the AccessKey ID and AccessKey secret of the Alibaba Cloud account to sign the signature string from the previous step. This process produces the digital signature for the API request.

  3. The client sends the API request content and the digital signature to the server.

  4. After the server receives the request, it repeats steps 1 and 2 to calculate the expected digital signature. The server retrieves the user key for the request from the backend.

  5. The server compares the expected digital signature with the one sent by the client. If they match, the request passes verification. Otherwise, the server rejects the request.

Generate a signature string for the request:

  1. Construct a canonicalized query string.

    Construct a canonicalized query string from the HTTP request parameters, excluding the Signature parameter, by following these steps:

    1. Sort the request parameters by parameter name in case-sensitive alphabetical order.

    2. URL-encode the sorted request parameters.

      URL-encode the request parameter names and values using the UTF-8 character set according to the following rules:

      • Characters A-Z, a-z, 0-9, and the special characters -, _, ., and ~ do not need to be encoded.

      • Other characters are percent-encoded into the "%XY" format, where XY is the hexadecimal representation of the character's ASCII code. For example, a double quotation mark (") is encoded as %22.

      • Extended UTF-8 characters are encoded into the "%XY%ZA..." format.

      • A space must be encoded as %20, not a plus sign (+).

      Note

      Most libraries that support URL encoding, such as java.net.URLEncoder in Java, encode according to the rules of the "application/x-www-form-urlencoded" Multipurpose Internet Mail Extensions (MIME) type. You can use this encoding method directly. Then, you must replace the plus sign (+) with %20, the asterisk (*) with %2A, and %7E with a tilde (~) in the encoded string to obtain a string that follows the rules described above.

    3. Use an equal sign (=) to connect the URL-encoded parameter name and value: percentEncode(ParameterKey) + "=" + percentEncode(ParameterValue).

    4. Use an ampersand (&) to connect the URL-encoded request parameter pairs, such as Action=CreateToken&Format=JSON.

      Note

      Do not add an ampersand (&) before the first parameter name in the string.

    5. Returns the canonicalized query string.

    For example:

    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 parameters.
    for (String key : sortedKeys) {
        canonicalizedQueryString.append("&")
                .append(percentEncode(key)).append("=")
                .append(percentEncode(queryParamsMap.get(key)));
    }
    queryString = canonicalizedQueryString.toString().substring(1);
    Note

    For the complete code, see the canonicalizedQuery function in the "Complete examples" section.

    Constructed canonicalized query string:

    AccessKeyId=LTA******3s2&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&SignatureMethod=HMAC-SHA1&SignatureNonce=f20b1beb-e5dc-4245-9e96-aa582e905c1a&SignatureVersion=1.0&Timestamp=2019-04-03T03%3A40%3A13Z&Version=2019-02-28

  2. Construct the string-to-sign.

    Create the string-to-sign by connecting the HTTP request method (GET), the URL-encoded URI of the request (/), and the canonicalized query string from step 1 with ampersands (&). The format is HTTPMethod + "&" + percentEncode("/") + "&" + percentEncode(queryString).

    The following code shows an example of how to construct the 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 the complete code, see the createStringToSign function in the "Complete examples" section.

    Constructed string-to-sign:

    GET&%2F&AccessKeyId%3DLTA******F3s%26Action%3DCreateToken%26Format%3DJSON%26RegionID%3Dcn-shanghai%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3Da237e025-07ea-4d87-bb04-d9b2712d871d%26SignatureVersion%3D1.0%26Timestamp%3D2019-04-19T03%253A31%253A40Z%26Version%3D2019-02-28
  3. Calculate the signature.

    • The signature is calculated using the HMAC-SHA1 algorithm with Base64, and the encoding is UTF-8.

    • Use the HMAC-SHA1 algorithm to calculate the digital signature of the string-to-sign from step 2. Use your AccessKey secret as the key. You must append an ampersand (&) to the AccessKey secret that is used for the calculation.

    • The signature must also be URL-encoded.

    The following code shows an example of how to calculate the signature:

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

    For the complete code, see the sign function in the "Complete examples" section.

    Calculated signature:

    # Signature string
    AKIktdPUMCV12fTh667BLXeuCtg=
    # URL-encoded result
    AKIktdPUMCV12fTh667BLXeuCtg%3D

    After you calculate the signature, connect the signature key-value pair with an equal sign (=) and add it to the request string from step 1 using an ampersand (&). You can then use this string as the HTTP GET request parameter to send to the server to obtain a token.

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

Quick test

You can use the following parameters to calculate a signature and compare the result with the expected output.

Note

The provided AccessKey ID and AccessKey secret are not real, and the timestamp has expired. A signature calculated with these parameters will fail if you try to obtain a token. These parameters are for signature calculation testing and comparison only.

  • AccessKey ID

    my_access_key_id

  • AccessKey secret:

    my_access_key_secret

  • Timestamp:

    2019-04-18T08:32:31Z

  • SignatureNonce:

    b924c8c3-6d03-4c5d-ad36-d984d3116788

The request parameters are as follows:

AccessKeyId:my_access_key_id
Action:CreateToken
Version:2019-02-28
Timestamp:2019-04-18T08:32:31Z
Format:JSON
RegionId:cn-shanghai
SignatureMethod:HMAC-SHA1
SignatureVersion:1.0
SignatureNonce:b924c8c3-6d03-4c5d-ad36-d984d3116788

  1. Canonicalize the request string.

    AccessKeyId=my_access_key_id&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&SignatureMethod=HMAC-SHA1&SignatureNonce=b924c8c3-6d03-4c5d-ad36-d984d3116788&SignatureVersion=1.0&Timestamp=2019-04-18T08%3A32%3A31Z&Version=2019-02-28

  2. Construct the string-to-sign.

    GET&%2F&AccessKeyId%3Dmy_access_key_id%26Action%3DCreateToken%26Format%3DJSON%26RegionId%3Dcn-shanghai%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3Db924c8c3-6d03-4c5d-ad36-d984d3116788%26SignatureVersion%3D1.0%26Timestamp%3D2019-04-18T08%253A32%253A31Z%26Version%3D2019-02-28
  3. Calculate the signature.

    hHq4yNsPitlfDJ2L0nQPdugdEzM=
    # URL-encoded result
    hHq4yNsPitlfDJ2L0nQPdugdEzM%3D
  4. Obtain the request string with the signature.

    Signature=hHq4yNsPitlfDJ2L0nQPdugdEzM%3D&AccessKeyId=my_access_key_id&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&SignatureMethod=HMAC-SHA1&SignatureNonce=b924c8c3-6d03-4c5d-ad36-d984d3116788&SignatureVersion=1.0&Timestamp=2019-04-18T08%3A32%3A31Z&Version=2019-02-28
  5. Assemble the HTTP request URL.

    http://nls-meta.cn-shanghai.aliyuncs.com/?Signature=hHq4yNsPitlfDJ2L0nQPdugdEzM%3D&AccessKeyId=my_access_key_id&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&SignatureMethod=HMAC-SHA1&SignatureNonce=b924c8c3-6d03-4c5d-ad36-d984d3116788&SignatureVersion=1.0&Timestamp=2019-04-18T08%3A32%3A31Z&Version=2019-02-28
  6. You can obtain the token using the HTTP request link from step 5 with a browser or curl.

    curl "http://nls-meta.cn-shanghai.aliyuncs.com/?Signature=${YourSignature}&AccessKeyId=${YourAccessKeyId}&Action=CreateToken&Format=JSON&RegionId=cn-shanghai&SignatureMethod=HMAC-SHA1&SignatureNonce=${YourRequestUUID}&SignatureVersion=1.0&Timestamp=${YourRequestTimestamp}&Version=2019-02-28"

Complete examples

Note
  • This topic provides sample code in Java and Python. You can implement client programs in other languages based on the protocol and these examples.

  • Before you call the API, you must configure environment variables to read your access credentials. The environment variables for the Intelligent Speech Interaction AccessKey ID and AccessKey secret are ALIYUN_AK_ID and ALIYUN_AK_SECRET, respectively.

  • Java example

    Dependency file:

    <!-- 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;
        /**
         * Get the timestamp.
         * The timestamp must be in UTC and comply with the ISO 8601 standard. The time zone is +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);
        }
        /**
         * Get the UUID.
         */
        public static String getUniqueNonce() {
            UUID uuid = UUID.randomUUID();
            return uuid.toString();
        }
        /**
         * URL-encode the string.
         * Use the UTF-8 character set to encode request parameters and their values according to 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 parameters, canonicalize them, and combine them into a request 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 request parameter string: " + queryString);
            } catch (UnsupportedEncodingException e) {
                System.out.println("UTF-8 encoding is not supported.");
                e.printStackTrace();
            }
            return queryString;
        }
        /***
         * Construct the string-to-sign.
         * @param method       The HTTP request method.
         * @param urlPath      The URI of the request.
         * @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("Constructed 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 Alibaba Cloud AccessKey secret, 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 the token and its expiration timestamp.
         * @param queryString Request parameters.
         */
        public static void processGETRequest(String queryString) {
            /**
             * Set up the HTTP GET request.
             * 1. Use the HTTP protocol.
             * 2. Token service domain name: nls-meta.cn-shanghai.aliyuncs.com
             * 3. Request path: /
             * 4. Set the request parameters.
             */
            String url = "http://nls-meta.cn-shanghai.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 submit the request to obtain a token: " + result);
                    }
                }
                else {
                    System.err.println("Failed to submit the request to obtain a 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 = System.getenv().get("ALIYUN_AK_ID");
            String accessKeySecret = System.getenv().get("ALIYUN_AK_SECRET");
            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", "cn-shanghai");
            queryParamsMap.put("SignatureMethod", "HMAC-SHA1");
            queryParamsMap.put("SignatureVersion", "1.0");
            queryParamsMap.put("SignatureNonce", getUniqueNonce());
            /**
             * 1. Construct the canonicalized query string.
             */
            String queryString = canonicalizedQuery(queryParamsMap);
            if (null == queryString) {
                System.out.println("Failed to construct the canonicalized query string!");
                return;
            }
            /**
             * 2. Construct the string-to-sign.
             */
            String method = "GET";  // The HTTP method for sending the request, GET.
            String urlPath = "/";   // Request path.
            String stringToSign = createStringToSign(method, urlPath, queryString);
            if (null == stringToSign) {
                System.out.println("Failed to construct 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 request string from Step 1.
             */
            String queryStringWithSign = "Signature=" + signature + "&" + queryString;
            System.out.println("Request string with signature: " + queryStringWithSign);
            /**
             * 5. Send an HTTP GET request to obtain the token.
             */
            processGETRequest(queryStringWithSign);
            if (token != null) {
                System.out.println("Obtained token: " + token + ", expiration timestamp (seconds): " + expireTime);
                // Convert the 10-digit timestamp to UTC+8.
                String expireDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(expireTime * 1000));
                System.out.println("Token expiration time (UTC+8): " + expireDate);
            }
        }
    }

  • Python example

    Note

    • Python 3.4 or later is required.

    • 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': 'cn-shanghai',
                          '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'}
            # Construct the canonicalized query string.
            query_string = AccessToken._encode_dict(parameters)
            print('Canonicalized query string: %s' % query_string)
            # Construct the 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)
            # URL-encode the signature.
            signature = AccessToken._encode_text(signature)
            print('URL-encoded signature: %s' % signature)
            # Call the service.
            full_url = 'http://nls-meta.cn-shanghai.aliyuncs.com/?Signature=%s&%s' % (signature, query_string)
            print('url: %s' % full_url)
            # Submit 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__":
        # User information.
        access_key_id = os.getenv('ALIYUN_AK_ID')      # Read AccessKey ID from environment variables.
        access_key_secret = os.getenv('ALIYUN_AK_SECRET')      # Read AccessKey secret from environment variables.
        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('Token expiration time (UTC+8): %s' % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(expire_time))))

References

You can also obtain a token in the following ways: