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.
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: *
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.
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:
The client generates a string signature based on the content of an API request that includes the HTTP request parameters and the request body.
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.
The client sends the signed API request to the server.
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.
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
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:
Sort the request parameters in alphabetical order. Parameter names are case-sensitive.
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.
Use an equal sign (=
) to connect the name and the value of each URL encoded request parameter. Example: percentEncode (parameter key) + "=" + percentEncode (parameter value)
.
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.
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;
}
String[] sortedKeys = queryParamsMap.keySet().toArray(new String[] {});
Arrays.sort(sortedKeys);
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
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:

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 + "&") );
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.
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
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
Create a string-to-sign.

Calculate and obtain the signature.
hHq4yNsPitlfDJ2L0nQPdugdEzM=
# The URL encoded signature
hHq4yNsPitlfDJ2L0nQPdugdEzM%3D
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
Obtain the HTTP request URL.
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.