All Products
Search
Document Center

Use HTTP or HTTPS to obtain a token

Last Updated: Oct 24, 2019

An access token is a credential for you to call an Intelligent Speech Interaction service. You can use the Alibaba Cloud public SDK to send a request for an access token. If you want to send an HTTP or HTTPS request for an access token from the client, you can follow the instructions in this topic.

Request

The client sends a request for an access token to the server. The server returns a response that contains the token creation result to the client. The client can send an HTTP or HTTPS request using the GET or POST method. The server provides the Alibaba Cloud pctowap open platform (POP) API. Therefore, the client needs to 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 for an access token.

URL

Protocol URL Method
HTTP/1.1 http://nlsmeta.ap-southeast-1.aliyuncs.com/ GET or POST

Request parameters

Note:

  • If you use the GET method, you need to add request parameters to the request URL as follows: /?Request parameter string.
  • If you use the POST method, you need to add request parameters to the request body.
Parameter Type Required Description
AccessKeyId String Yes The AccessKey ID that Alibaba Cloud issues to you. Set this parameter to the AccessKey ID of your Alibaba Cloud account.
Action String Yes The operation that you want to perform. Set this parameter to CreateToken.
Version String Yes The version of the POP API. Set this parameter to 2019-07-17.
Format String Yes The format of the response. Set this parameter to JSON.
RegionId String Yes The region ID of the requested Intelligent Speech Interaction 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. Do not use the local time, such as UTC+8. For example, a value of 2019-04-03T06:15:03Z indicates 06:15:03 on April 3, 2019, UTC+0.
SignatureMethod String Yes The signature algorithm. Set this parameter to HMAC-SHA1.
SignatureVersion String Yes The version of the signature algorithm. Set this parameter to 1.0.
SignatureNonce String Yes The unique random number that is used to prevent replay attacks. This UUID uniquely identifies the request. The value is in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx(8-4-4-4-12) format. For example, 8d1e6a7a-f44e-40d5-aedb-fe4a1c80f434.
Signature String Yes The signature string calculated based on request parameters. For more information about the signature calculation method, see Signature mechanism.

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 value in each pair are separated with a colon (:). The following table describes the fields of the HTTP request header.

Field Type Required Description
Host String No The endpoint of the requested Intelligent Speech Interaction service. Set this parameter to nlsmeta.ap-southeast-1.aliyuncs.com. The domain name is usually automatically resolved based on the request URL.
Accept String No The type of the content that the client can accept. Set this parameter 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 parameter to application/x-www-form-urlencoded.

Sample requests

HTTP GET request:

  1. GET /?Signature=O0s6pfeOxtFM6YKSZKQdSyPR9Vs%3D&AccessKeyId=LTA******F3s&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-07-17 HTTP/1.1
  2. Host: nlsmeta.ap-southeast-1.aliyuncs.com
  3. User-Agent: curl/7.49.1
  4. Accept: */*

HTTP POST request:

  1. POST / HTTP/1.1
  2. Host: nlsmeta.ap-southeast-1.aliyuncs.com
  3. User-Agent: curl/7.49.1
  4. Accept: */*
  5. Content-type: application/x-www-form-urlencoded
  6. Content-Length: 276
  7. SignatureVersion=1.0&Action=CreateToken&Format=JSON&SignatureNonce=8d1e6a7a-f44e-40d5-aedb-fe4a1c80f434&Version=2019-07-17&AccessKeyId=LTA******F3s&Signature=oT8A8RgvFE1tMD%2B3hDbGuoMQSi8%3D&SignatureMethod=HMAC-SHA1&RegionId=ap-southeast-1&Timestamp=2019-03-25T09%3A07%3A52Z

Response

After the client sends an HTTP request for an access token, the server returns a response that contains the result in JSON format. The response is the same for both the GET and POST methods.

  • Sample 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.
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 on March 29, 2019, UTC+8.
  1. HTTP/1.1 200 OK
  2. Date: Mon, 25 Mar 2019 09:29:24 GMT
  3. Content-Type: application/json; charset=UTF-8
  4. Content-Length: 216
  5. Connection: keep-alive
  6. Access-Control-Allow-Origin: *
  7. Access-Control-Allow-Methods: POST, GET, OPTIONS
  8. Access-Control-Allow-Headers: X-Requested-With, X-Sequence, _aop_secret, _aop_signature
  9. Access-Control-Max-Age: 172800
  10. Server: Jetty(7.2.2.v20101205)
  11. {"NlsRequestId":"dd05a301b40441c99a2671905325fb1f","RequestId":"E11F2DC2-0163-4D97-A704-0BD28045608A","ErrMsg":"","Token":{"ExpireTime":1553592564,"Id":"889******166","UserId":"150**********151"}}

The response body in JSON format is as follows:

  1. {
  2. "NlsRequestId": "dd05a301b40441c99a2671905325fb1f",
  3. "RequestId": "E11F2DC2-0163-4D97-A704-0BD28045608A",
  4. "ErrMsg": "",
  5. "Token": {
  6. "ExpireTime": 1553592564,
  7. "Id": "889******166",
  8. "UserId": "150**********151"
  9. }
  10. }
  • Sample 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 request parameters are set correctly based on the error code and error message. If you cannot resolve the error, you can open a ticket to submit the response.

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

  1. HTTP/1.1 404 Not Found
  2. Date: Thu, 28 Mar 2019 07:23:01 GMT
  3. Content-Type: application/json; charset=UTF-8
  4. Content-Length: 290
  5. Connection: keep-alive
  6. Access-Control-Allow-Origin: *
  7. Access-Control-Allow-Methods: POST, GET, OPTIONS
  8. Access-Control-Allow-Headers: X-Requested-With, X-Sequence, _aop_secret, _aop_signature
  9. Access-Control-Max-Age: 172800
  10. Server: Jetty(7.2.2.v20101205)
  11. {"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-CD4365C2D1E1","HostId":"nlsmeta.ap-southeast-1.aliyuncs.com","Code":"InvalidAccessKeyId.NotFound"}

The response body in JSON format is as follows:

  1. {
  2. "Recommend": "https://error-center.aliyun.com/status/search?Keyword=InvalidAccessKeyId.NotFound&source=PopGw",
  3. "Message": "Specified access key is not found.",
  4. "RequestId": "A51587CB-5193-4DB8-9AED-CD4365C2D1E1",
  5. "HostId": "nlsmeta.ap-southeast-1.aliyuncs.com",
  6. "Code": "InvalidAccessKeyId.NotFound"
  7. }

Signature mechanism

The server authenticates each client that sends a POP API request. Therefore, no matter whether the client sends an HTTP or HTTPS request, the request must contain signature information. Based on the signature mechanism, the server can identify the client that sends the API request and confirm whether the request is tampered with during network transmission.

Security authentication process

The signature calculation process uses the AccessKey ID and AccessKey secret of your Alibaba Cloud account and the HMAC-SHA1 algorithm for symmetric encryption. The process is as follows:

  1. The client generates a signature string based on the content of an API request, including the HTTP request parameters and request body.
  2. The client uses the AccessKey ID and AccessKey secret of your Alibaba Cloud account to encrypt the signature string generated in step 1 and obtains a digital signature for this API request.
  3. The client sends the content and digital signature of the API request to the server.
  4. After receiving the API request, the server obtains the AccessKey ID and AccessKey secret used by this request from the backend and repeats steps 1 and 2 to calculate the expected digital signature for this request.
  5. The server compares the expected digital signature with the digital signature sent from the client. If they are the same, the API request passes the security authentication. Otherwise, the server immediately rejects this request.

Generate a signature string for a request

1. Construct a canonicalized query string.

Construct a canonicalized query string based on the HTTP request parameters, excluding the Signature parameter. The procedure is as follows:

  1. Sort request parameters alphabetically based on the initial letters of parameter names. Parameter names are case-sensitive.
  2. UTF-8 encode and canonicalize the sorted request parameters.Use UTF-8 to perform URL encoding for the names and values of request parameters according to the following rules:
    • Do not encode uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and characters including the hyphen (-), underscore (_), period (.), and tilde (~).
    • Encode other characters into the %XY format, where XY is the hexadecimal value of the ASCII code corresponding to a character. For example, a double quotation mark (“) is encoded as %22.
    • Encode the extended UTF-8 characters into the %XY%ZA… format.
    • Encode a space ( ) as %20 but not a plus sign (+).Note: Generally, libraries that support URL encoding (such as java.net.URLEncoder in Java) are all encoded according to the rules for the “application/x-www-form-urlencoded” MIME type. 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 value of each URL encoded request parameter as a key-value pair. For example, percentEncode (Key) + "=" + percentEncode (Value).
  4. Use an ampersand (&) to connect the key-value pairs of the URL encoded request parameters. For example, Action=CreateToken&Format=JSON.
  5. Return the canonicalized query string. Note: Do not add an ampersand (&) before the first parameter name of the string.

Use the following sample code to construct a canonicalized query string:

  1. String percentEncode(String value) throws UnsupportedEncodingException {
  2. return value != null ? URLEncoder.encode(value, URL_ENCODING)
  3. .replace("+", "%20")
  4. .replace("*", "%2A")
  5. .replace("%7E", "~") : null;
  6. }
  7. // Sort request parameters.
  8. String[] sortedKeys = queryParamsMap.keySet().toArray(new String[] {});
  9. Arrays.sort(sortedKeys);
  10. // Encode and concatenate the sorted request parameters.
  11. for (String key : sortedKeys) {
  12. canonicalizedQueryString.append("&")
  13. .append(percentEncode(key)).append("=")
  14. .append(percentEncode(queryParamsMap.get(key)));
  15. }
  16. queryString = canonicalizedQueryString.toString().substring(1);

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

The following example shows a canonicalized query string:

  1. 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-07-17

2. Construct the StringToSign string.

Use an ampersand (&) to connect the HTTP request method (such as GET), the URL encoded request URL (such as a forward slash (/)), and the URL encoded canonicalized query string obtained in step 1. The StringToSign string is constructed as follows:

HTTPMethod + "&" + percentEncode("/") + "&" + percentEncode(queryString)

Use the following sample code to construct the StringToSign string:

  1. StringBuilder strBuilderSign = new StringBuilder();
  2. strBuilderSign.append(HTTPMethod);
  3. strBuilderSign.append("&");
  4. strBuilderSign.append(percentEncode(urlPath));
  5. strBuilderSign.append("&");
  6. strBuilderSign.append(percentEncode(queryString));
  7. stringToSign = strBuilderSign.toString();

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

The following example shows a StringToSign string:strToSign

3. Calculate the signature.

  • Use the HMAC-SHA1 algorithm and Base64 encoding to calculate the digital signature, and then use UTF-8 encoding to encode the calculated digital signature.
  • Based on your AccessKey secret, use the HMAC-SHA1 algorithm to calculate the digital signature based on the StringToSign string constructed in step 2. You must add an ampersand (&) after the AccessKey secret used to calculate the digital signature.
  • Perform URL encoding for the calculated digital signature.

Use the following sample code to calculate the signature:

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

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

The following example shows a calculated signature:

  1. # The signature string.
  2. AKIktdPUMCV12fTh667BLXeuCtg=
  3. # The URL encoded signature.
  4. AKIktdPUMCV12fTh667BLXeuCtg%3D

After calculating the signature, use an equal sign (=) to connect the key-value pair of the Signature parameter. In addition, use an ampersand (&) to connect the signature key-value pair and the canonicalized query string obtained in step 1. Then, the client can send the HTTP GET request containing the signature to the server to obtain an access token.

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

Quick test

You can use the following parameters to calculate a signature and test the calculated signature.

Note: The AccessKey ID and AccessKey secret are not real. The timestamp is an expired time. You cannot obtain an access token by using the signature calculated based on these parameters. They 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

Use the following request parameters:

  1. AccessKeyId:my_access_key_id
  2. Action:CreateToken
  3. Version:2019-07-17
  4. Timestamp:2019-04-18T08:32:31Z
  5. Format:JSON
  6. RegionId:ap-southeast-1
  7. SignatureMethod:HMAC-SHA1
  8. SignatureVersion:1.0
  9. SignatureNonce:b924c8c3-6d03-4c5d-ad36-d984d3116788
  1. Construct a canonicalized query string.
  1. 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-07-17
  1. Construct the StringToSign string.

Format:

HTTPMethod + "&" + percentEncode("/") + "&" + percentEncode(queryString)

stringToSign

  1. Calculate the signature.
  1. hHq4yNsPitlfDJ2L0nQPdugdEzM=
  2. # The URL encoded signature.
  3. hHq4yNsPitlfDJ2L0nQPdugdEzM%3D
  1. Add the signature to the canonicalized query string.
  1. 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-07-17
  1. Obtain the HTTP request URL.
  1. 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-07-17
  1. Replace relevant parameters in the HTTP request URL obtained in step 5. Use a browser or run a curl command to obtain an access token.
  1. 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-07-17"

Complete sample code

Note: This topic provides Java sample code and Python sample code for your reference. You can write the code in other languages according to relevant protocols and the sample code provided in this topic.

Java demo

Dependencies:

  1. <!-- http://mvnrepository.com/artifact/com.alibaba/fastjson -->
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>fastjson</artifactId>
  5. <version>1.2.49</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>com.squareup.okhttp3</groupId>
  9. <artifactId>okhttp</artifactId>
  10. <version>3.9.1</version>
  11. </dependency>

Demo code:

  1. import com.alibaba.fastjson.JSON;
  2. import com.alibaba.fastjson.JSONObject;
  3. import okhttp3.OkHttpClient;
  4. import okhttp3.Request;
  5. import okhttp3.Response;
  6. import javax.crypto.Mac;
  7. import javax.crypto.spec.SecretKeySpec;
  8. import javax.xml.bind.DatatypeConverter;
  9. import java.io.UnsupportedEncodingException;
  10. import java.net.URLEncoder;
  11. import java.security.InvalidKeyException;
  12. import java.security.NoSuchAlgorithmException;
  13. import java.text.SimpleDateFormat;
  14. import java.util.Arrays;
  15. import java.util.Date;
  16. import java.util.HashMap;
  17. import java.util.Map;
  18. import java.util.SimpleTimeZone;
  19. import java.util.UUID;
  20. public class CreateToken {
  21. private final static String TIME_ZONE = "GMT";
  22. private final static String FORMAT_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'";
  23. private final static String URL_ENCODING = "UTF-8";
  24. private static final String ALGORITHM_NAME = "HmacSHA1";
  25. private static final String ENCODING = "UTF-8";
  26. private static String token = null;
  27. private static long expireTime = 0;
  28. /**
  29. * Obtain the current timestamp.
  30. * Specify the time in the ISO 8601 standard in the yyyy-MM-ddTHH:mm:ssZ format. The time must be in UTC+0.
  31. */
  32. public static String getISO8601Time(Date date) {
  33. Date nowDate = date;
  34. if (null == date) {
  35. nowDate = new Date();
  36. }
  37. SimpleDateFormat df = new SimpleDateFormat(FORMAT_ISO8601);
  38. df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
  39. return df.format(nowDate);
  40. }
  41. /**
  42. * Obtain the UUID of the request.
  43. */
  44. public static String getUniqueNonce() {
  45. UUID uuid = UUID.randomUUID();
  46. return uuid.toString();
  47. }
  48. /**
  49. * Perform URL encoding.
  50. * Use UTF-8 to encode the names and values of request parameters according to RFC 3986.
  51. */
  52. public static String percentEncode(String value) throws UnsupportedEncodingException {
  53. return value != null ? URLEncoder.encode(value, URL_ENCODING).replace("+", "%20")
  54. .replace("*", "%2A").replace("%7E", "~") : null;
  55. }
  56. /***
  57. * Sort request parameters, and encode and concatenate the sorted request parameters to construct a canonicalized query string.
  58. * @param queryParamsMap The request parameters.
  59. * @return The canonicalized query string.
  60. */
  61. public static String canonicalizedQuery( Map<String, String> queryParamsMap) {
  62. String[] sortedKeys = queryParamsMap.keySet().toArray(new String[] {});
  63. Arrays.sort(sortedKeys);
  64. String queryString = null;
  65. try {
  66. StringBuilder canonicalizedQueryString = new StringBuilder();
  67. for (String key : sortedKeys) {
  68. canonicalizedQueryString.append("&")
  69. .append(percentEncode(key)).append("=")
  70. .append(percentEncode(queryParamsMap.get(key)));
  71. }
  72. queryString = canonicalizedQueryString.toString().substring(1);
  73. System.out.println("Canonicalized query string: " + queryString);
  74. } catch (UnsupportedEncodingException e) {
  75. System.out.println("UTF-8 encoding is not supported.");
  76. e.printStackTrace();
  77. }
  78. return queryString;
  79. }
  80. /***
  81. * Construct the StringToSign string.
  82. * @param method The HTTP request method.
  83. * @param urlPath The HTTP request URL.
  84. * @param queryString The canonicalized query string.
  85. * @return The StringToSign string.
  86. */
  87. public static String createStringToSign(String method, String urlPath, String queryString) {
  88. String stringToSign = null;
  89. try {
  90. StringBuilder strBuilderSign = new StringBuilder();
  91. strBuilderSign.append(method);
  92. strBuilderSign.append("&");
  93. strBuilderSign.append(percentEncode(urlPath));
  94. strBuilderSign.append("&");
  95. strBuilderSign.append(percentEncode(queryString));
  96. stringToSign = strBuilderSign.toString();
  97. System.out.println("StringToSign string: " + stringToSign);
  98. } catch (UnsupportedEncodingException e) {
  99. System.out.println("UTF-8 encoding is not supported.");
  100. e.printStackTrace();
  101. }
  102. return stringToSign;
  103. }
  104. /***
  105. * Calculate the signature.
  106. * @param stringToSign The StringToSign string.
  107. * @param accessKeySecret The AccessKey secret appended with an ampersand (&).
  108. * @return The calculated signature.
  109. */
  110. public static String sign(String stringToSign, String accessKeySecret) {
  111. try {
  112. Mac mac = Mac.getInstance(ALGORITHM_NAME);
  113. mac.init(new SecretKeySpec(
  114. accessKeySecret.getBytes(ENCODING),
  115. ALGORITHM_NAME
  116. ));
  117. byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING));
  118. String signBase64 = DatatypeConverter.printBase64Binary(signData);
  119. System.out.println("Calculated signature: " + signBase64);
  120. String signUrlEncode = percentEncode(signBase64);
  121. System.out.println("URL encoded signature: " + signUrlEncode);
  122. return signUrlEncode;
  123. } catch (NoSuchAlgorithmException e) {
  124. throw new IllegalArgumentException(e.toString());
  125. } catch (UnsupportedEncodingException e) {
  126. throw new IllegalArgumentException(e.toString());
  127. } catch (InvalidKeyException e) {
  128. throw new IllegalArgumentException(e.toString());
  129. }
  130. }
  131. /***
  132. * Send an HTTP GET request to obtain an access token and the timestamp that indicates the validity period of the access token.
  133. * @param queryString The request parameters.
  134. */
  135. public static void processGETRequest(String queryString) {
  136. /**
  137. * Create an HTTP GET request.
  138. * 1. Use HTTP.
  139. * 2. Use the endpoint of the requested Intelligent Speech Interaction service: nlsmeta.ap-southeast-1.aliyuncs.com.
  140. * 3. Use a forward slash (/).
  141. * 4. Set request parameters.
  142. */
  143. String url = "http://nlsmeta.ap-southeast-1.aliyuncs.com";
  144. url = url + "/";
  145. url = url + "?" + queryString;
  146. System.out.println("HTTP request URL: " + url);
  147. Request request = new Request.Builder()
  148. .url(url)
  149. .header("Accept", "application/json")
  150. .get()
  151. .build();
  152. try {
  153. OkHttpClient client = new OkHttpClient();
  154. Response response = client.newCall(request).execute();
  155. String result = response.body().string();
  156. if (response.isSuccessful()) {
  157. JSONObject rootObj = JSON.parseObject(result);
  158. JSONObject tokenObj = rootObj.getJSONObject("Token");
  159. if (tokenObj != null) {
  160. token = tokenObj.getString("Id");
  161. expireTime = tokenObj.getLongValue("ExpireTime");
  162. }
  163. else{
  164. System.err.println("Failed to send the request for an access token: " + result);
  165. }
  166. }
  167. else {
  168. System.err.println("Failed to send the request for an access token: " + result);
  169. }
  170. response.close();
  171. } catch (Exception e) {
  172. e.printStackTrace();
  173. }
  174. }
  175. public static void main(String args[]) {
  176. if (args.length < 2) {
  177. System.err.println("CreateTokenDemo need params: <AccessKey Id> <AccessKey Secret>");
  178. System.exit(-1);
  179. }
  180. String accessKeyId = args[0];
  181. String accessKeySecret = args[1];
  182. System.out.println(getISO8601Time(null));
  183. // The request parameters.
  184. Map<String, String> queryParamsMap = new HashMap<String, String>();
  185. queryParamsMap.put("AccessKeyId", accessKeyId);
  186. queryParamsMap.put("Action", "CreateToken");
  187. queryParamsMap.put("Version", "2019-07-17");
  188. queryParamsMap.put("Timestamp", getISO8601Time(null));
  189. queryParamsMap.put("Format", "JSON");
  190. queryParamsMap.put("RegionId", "ap-southeast-1");
  191. queryParamsMap.put("SignatureMethod", "HMAC-SHA1");
  192. queryParamsMap.put("SignatureVersion", "1.0");
  193. queryParamsMap.put("SignatureNonce", getUniqueNonce());
  194. /**
  195. * 1. Construct a canonicalized query string.
  196. */
  197. String queryString = canonicalizedQuery(queryParamsMap);
  198. if (null == queryString) {
  199. System.out.println("Failed to construct the canonicalized query string.") ;
  200. return;
  201. }
  202. /**
  203. * 2. Construct the StringToSign string.
  204. */
  205. String method = "GET"; // The HTTP request method, such as GET.
  206. String urlPath = "/"; // The HTTP request URL.
  207. String stringToSign = createStringToSign(method, urlPath, queryString);
  208. if (null == stringToSign) {
  209. System.out.println("Failed to construct the StringToSign string.");
  210. return;
  211. }
  212. /**
  213. * 3. Calculate the signature.
  214. */
  215. String signature = sign(stringToSign, accessKeySecret + "&");
  216. if (null == signature) {
  217. System.out.println("Failed to calculate the signature.") ;
  218. return;
  219. }
  220. /**
  221. * 4. Add the signature to the canonicalized query string obtained in step 1.
  222. */
  223. String queryStringWithSign = "Signature=" + signature + "&" + queryString;
  224. System.out.println("Query string that contains a signature: " + queryStringWithSign);
  225. /**
  226. * 5. Send the HTTP GET request to obtain an access token.
  227. */
  228. processGETRequest(queryStringWithSign);
  229. if (token != null) {
  230. System.out.println("Obtained token: " + token + ", Timestamp of the validity period (Unit: seconds): " + expireTime);
  231. // Convert the 10-digit timestamp to a time in UTC+8.
  232. String expireDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(expireTime * 1000));
  233. System.out.println("Validity period of the access token in UTC+8: " + expireDate);
  234. }
  235. }
  236. }

Python demo

Note:

  • Python version requirement: Python 3.4 or later.
  • Run the following command to install the Python HTTP library Requests:

    1. pip install requests

Demo code:

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import base64
  4. import hashlib
  5. import hmac
  6. import requests
  7. import time
  8. import uuid
  9. from urllib import parse
  10. class AccessToken:
  11. @staticmethod
  12. def _encode_text(text):
  13. encoded_text = parse.quote_plus(text)
  14. return encoded_text.replace('+', '%20').replace('*', '%2A').replace('%7E', '~')
  15. @staticmethod
  16. def _encode_dict(dic):
  17. keys = dic.keys()
  18. dic_sorted = [(key, dic[key]) for key in sorted(keys)]
  19. encoded_text = parse.urlencode(dic_sorted)
  20. return encoded_text.replace('+', '%20').replace('*', '%2A').replace('%7E', '~')
  21. @staticmethod
  22. def create_token(access_key_id, access_key_secret):
  23. parameters = {'AccessKeyId': access_key_id,
  24. 'Action': 'CreateToken',
  25. 'Format': 'JSON',
  26. 'RegionId': 'ap-southeast-1',
  27. 'SignatureMethod': 'HMAC-SHA1',
  28. 'SignatureNonce': str(uuid.uuid1()),
  29. 'SignatureVersion': '1.0',
  30. 'Timestamp': time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
  31. 'Version': '2019-07-17'}
  32. # Construct a canonicalized query string.
  33. query_string = AccessToken._encode_dict(parameters)
  34. print('Canonicalized query string: %s' % query_string)
  35. # Construct the StringToSign string.
  36. string_to_sign = 'GET' + '&' + AccessToken._encode_text('/') + '&' + AccessToken._encode_text(query_string)
  37. print('StringToSign string: %s' % string_to_sign)
  38. # Calculate the signature.
  39. secreted_string = hmac.new(bytes(access_key_secret + '&', encoding='utf-8'),
  40. bytes(string_to_sign, encoding='utf-8'),
  41. hashlib.sha1).digest()
  42. signature = base64.b64encode(secreted_string)
  43. print('Signature: %s' % signature)
  44. # Perform URL encoding.
  45. signature = AccessToken._encode_text(signature)
  46. print('URL encoded signature: %s' % signature)
  47. # Create an HTTP GET request.
  48. full_url = 'http://nlsmeta.ap-southeast-1.aliyuncs.com/?Signature=%s&%s' % (signature, query_string)
  49. print('url: %s' % full_url)
  50. # Send the HTTP GET request.
  51. response = requests.get(full_url)
  52. if response.ok:
  53. root_obj = response.json()
  54. key = 'Token'
  55. if key in root_obj:
  56. token = root_obj[key]['Id']
  57. expire_time = root_obj[key]['ExpireTime']
  58. return token, expire_time
  59. print(response.text)
  60. return None, None
  61. if __name__ == "__main__":
  62. # The user information.
  63. access_key_id = 'Your AccessKey ID'
  64. access_key_secret = 'Your AccessKey secret'
  65. token, expire_time = AccessToken.create_token(access_key_id, access_key_secret)
  66. print('token: %s, expire time(s): %s' % (token, expire_time))
  67. if expire_time:
  68. print('Validity period of the access token in UTC+8: %s' % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(expire_time))))