このトピックでは、API操作を呼び出すことによってアクセストークンを取得する方法について説明します。
リクエスト
クライアントはサーバーにリクエストを送信してアクセストークンを取得します。サーバーはアクセストークンを作成し、クライアントに応答を返します。クライアントは、GETメソッドまたはPOSTメソッドを使用してHTTPまたはHTTPSリクエストを送信できます。サーバーはPortable OpenAPI Proxy(POP)APIを提供します。そのため、クライアントはAlibaba Cloud POP署名メカニズムを使用して各リクエストに署名を追加する必要があります。
リクエストパラメータの設定は、HTTPとHTTPSで同じです。このトピックでは、HTTPを例として使用して、アクセストークンを取得するためのリクエストを送信する方法について説明します。
URL
プロトコル
URL
メソッド
HTTP/1.1
http://nlsmeta.ap-southeast-1.aliyuncs.com/
GET/POST
リクエストパラメータ
パラメータ
タイプ
必須
説明
AccessKeyId
String
はい
Alibaba CloudアカウントのAccessKey ID。
Action
String
はい
実行するAPI操作。このパラメータをCreateTokenに設定します。
Version
String
はい
POP APIのバージョン番号。このパラメータを 2019-02-28 に設定します。
Format
String
はい
レスポンスの形式。このパラメータをJSONに設定します。
RegionId
String
はい
サービスが配置されているリージョン ID。 ap-southeast-1 を設定します。
Timestamp
String
はい
リクエストのタイムスタンプ。ISO 8601 標準の yyyy-MM-ddTHH:mm:ssZ 形式で時間を指定します。時間は UTC+0 でなければなりません。たとえば、2019-04-03T06:15:03Z という値は、2019年 4月 3日 06:15:03 を指定します。
SignatureMethod
String
はい
署名アルゴリズム。このパラメータをHMAC-SHA1に設定します。
SignatureVersion
String
はい
署名アルゴリズムのバージョン番号。このパラメータを 1.0 に設定します。
SignatureNonce
String
はい
リプレイ攻撃を防ぐために使用される一意の乱数。異なるリクエストには異なる番号を使用する必要があります。値はxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx(8-4-4-4-12)形式です。例:8d1e6a7a-f44e-40d5-aedb-fe4a1c80f434。
Signature
String
はい
すべてのリクエストパラメータに基づいて計算される署名文字列。署名の計算方法の詳細については、「署名メカニズム」セクションを参照してください。
説明GETメソッドを使用する場合は、
/?request parameter stringの形式でリクエスト行にリクエストパラメータを追加する必要があります。POSTメソッドを使用する場合は、リクエストボディにリクエストパラメータを追加する必要があります。
HTTPリクエストヘッダー
HTTPリクエストヘッダーは、キーと値のペアで構成されます。各キーと値のペアは、1行を占めるフィールドです。各ペアのキーと値はコロン(:)で区切られます。次の表に、HTTPリクエストヘッダーのフィールドを示します。
パラメータ
タイプ
必須
説明
Host
String
いいえ
リクエストされたIntelligent Speech Interaction サービスのエンドポイント。このフィールドを
nlsmeta.ap-southeast-1.aliyuncs.comに設定します。このエンドポイントは通常、リクエスト URL に基づいて自動的に解決されます。Accept
String
いいえ
クライアントが受信できるコンテンツのタイプ。このフィールドを
application/jsonに設定します。このフィールドを指定しない場合、デフォルト値 */* が使用されます。Content-type
String
POST メソッドの場合は必須
POSTメソッドが使用される場合のリクエストボディのデータ形式。このフィールドを
application/x-www-form-urlencodedに設定します。
リクエストの例:
HTTP GET リクエスト
GET /?Signature=O0s6pfeOxtFM6YKSZKQdSyPR9Vs%3D&AccessKeyId=LTAF3sAA****&Action=CreateToken&Format=JSON&RegionId=ap-southeast-1&SignatureMethod=HMAC-SHA1&SignatureNonce=a1f01895-6ff1-43c1-ba15-6c109fa00106&SignatureVersion=1.0&Timestamp=2019-03-27T09%3A51%3A25Z&Version=2019-02-28 HTTP/1.1 Host: nlsmeta.ap-southeast-1.aliyuncs.com User-Agent: curl/7.49.1 Accept: */*HTTP POST リクエスト
POST / HTTP/1.1 Host: nlsmeta.ap-southeast-1.aliyuncs.com User-Agent: curl/7.49.1 Accept: */* Content-type: application/x-www-form-urlencoded Content-Length: 276 SignatureVersion=1.0&Action=CreateToken&Format=JSON&SignatureNonce=8d1e6a7a-f44e-40d5-aedb-fe4a1c80f434&Version=2019-02-28&AccessKeyId=LTAF3sAA****&Signature=oT8A8RgvFE1tMD%2B3hDbGuoMQSi8%3D&SignatureMethod=HMAC-SHA1&RegionId=ap-southeast-1&Timestamp=2019-03-25T09%3A07%3A52Z
レスポンス:
クライアントがアクセストークンを取得するためのHTTPリクエストを送信した後、サーバーはレスポンスを返します。結果は、レスポンスにJSON文字列として格納されます。レスポンスは、GETメソッドとPOSTメソッドで同じです。
成功レスポンス
HTTPステータスコードは 200 です。次の表に、レスポンスパラメータを示します。
パラメータ
タイプ
説明
Token
Object
アクセストークンと、アクセストークンの有効期間を示すタイムスタンプを含むトークンオブジェクト。
Id
String
リクエストに割り当てられたアクセストークン。
ExpireTime
Long
アクセストークンの有効期間を示すタイムスタンプ。単位:秒。たとえば、値 1553825814 は、アクセストークンが 2019 年 3 月 29 日 10:16:54 (UTC+8) まで有効であることを示します。
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****"}}次のコードは、JSON形式のレスポンスボディを示しています。
{ "NlsRequestId": "dd05a301b40441c99a2671905325****", "RequestId": "E11F2DC2-0163-4D97-A704-0BD28045****", "ErrMsg": "", "Token": { "ExpireTime": 1553592564, "Id": "889******166", "UserId": "150**********151" } }
エラーレスポンス
HTTPステータスコードは 200 ではありません。次の表に、レスポンスパラメータを示します。
パラメータ
タイプ
説明
RequestId
String
リクエストのID。
Message
String
エラーレスポンスのエラーメッセージ。
Code
String
エラーレスポンスのエラーコード。
説明エラーコードとエラーメッセージに基づいて、リクエストパラメータが正しく設定されているかどうかを確認します。
次の例は、無効な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"}次のコードは、JSON形式のレスポンスボディを示しています。
{ "Recommend": "https://error-center.aliyun.com/status/search?Keyword=InvalidAccessKeyId.NotFound&source=PopGw", "Message": "Specified access key is not found.", "RequestId": "A51587CB-5193-4DB8-9AED-CD4365C2****", "HostId": "nlsmeta.ap-southeast-1.aliyuncs.com", "Code": "InvalidAccessKeyId.NotFound" }
署名メカニズム
サーバーがPOP APIリクエストを受信すると、API呼び出し元のIDを認証します。そのため、HTTPまたはHTTPSリクエストには署名情報が含まれている必要があります。署名メカニズムに基づいて、サーバーはAPIリクエストを送信したユーザーを識別し、ネットワーク転送中にAPIリクエストが改ざんされていないことを確認できます。
セキュリティ検証プロセス
Intelligent Speech Interactionは、HMAC-SHA1アルゴリズムを使用して、Alibaba CloudアカウントのAccessKey IDとAccessKeyシークレットに基づいて対称暗号化を実装します。次のプロセスは、APIリクエストを検証する方法を示しています。
クライアントは、HTTPリクエストパラメータとリクエストボディを含むAPIリクエストのコンテンツに基づいて文字列署名を生成します。
クライアントは、Alibaba CloudアカウントのAccessKey IDとAccessKeyシークレットを使用して、手順1で生成された署名文字列を暗号化します。次に、クライアントはこのAPIリクエストのデジタル署名を取得します。
クライアントは、署名付きAPIリクエストをサーバーに送信します。
サーバーはAPIリクエストを受信した後、手順1と2を繰り返して、APIリクエストの予期されるデジタル署名を計算します。サーバーは、バックエンドからAPIリクエストで使用されるAccessKey IDとAccessKeyシークレットを取得できます。
サーバーは、予期されるデジタル署名とクライアントから送信されたデジタル署名を比較します。署名が同じであれば、リクエストはセキュリティ検証に合格します。署名が異なれば、サーバーはAPIリクエストを拒否します。
APIリクエストの署名文字列を生成する
正規化されたクエリ文字列を作成します。
Signatureパラメータを含めずに、HTTPリクエストパラメータに基づいて正規化されたクエリ文字列を作成します。正規化されたクエリ文字列を作成するには、次の手順を実行します。
リクエストパラメータをアルファベット順にソートします。パラメータ名は大文字と小文字が区別されます。
パラメータをエンコードします。ソートされたリクエストパラメータを正規化します。
次のルールに基づいて、リクエストパラメータの名前と値を
UTF-8でエンコードします。大文字、小文字、数字、およびハイフン(
-)、アンダースコア(_)、ピリオド(.)、チルダ(~)などの特殊文字はエンコードする必要はありません。その他の文字は、%XY形式でパーセントエンコードする必要があります。XYは、16進表記の文字のASCIIコードを表します。たとえば、二重引用符(")は%22としてエンコードされます。
拡張
UTF-8文字は、%XY%ZA…形式でエンコードする必要があります。スペースは%20としてエンコードする必要があります。スペースをプラス記号(
+)としてエンコードしないでください。
説明java.net.URLEncoderなどのURLエンコードをサポートするほとんどのライブラリは、application/x-www-form-urlencodedのエンコードルールに基づいて作成されます。 application/x-www-form-urlencodedは、Multipurpose Internet Mail Extensions(MIME)のサブタイプです。このエンコード方式を使用する場合、エンコードされた文字列のプラス記号(
+)を%20に、アスタリスク(*)を%2Aに、%7Eをチルダ(~)に置き換えて、必要な文字列を取得できます。等号(
=)を使用して、URLエンコードされた各リクエストパラメータの名前と値を接続します。例:percentEncode (parameter key) + "=" + percentEncode (parameter value)。アンパサンド(
&)を使用して、手順cで生成されたURLエンコードされたリクエストパラメータのキーと値のペアを接続します。例:Action=CreateToken&Format=JSON。説明正規化されたクエリ文字列の最初のパラメータ名の前にアンパサンド(
&)を追加しないでください。正規化されたクエリ文字列を返します。
サンプルコード:
// パラメータキーをソートします。 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);説明完全なサンプルコードの詳細については、「完全なサンプルコード」セクションの
canonicalizedQuery関数を参照してください。次の正規化されたクエリ文字列が作成されます。
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署名対象文字列を作成します。
署名対象文字列は、HTTPリクエストメソッド、URLエンコードされたURL、および手順1で取得したURLエンコードされた正規化クエリ文字列で構成されます。アンパサンド(
&)を使用して、これらの要素を次の形式で連結します。HTTPMethod + "&" + percentEncode("/") + "&" + percentEncode(queryString)。次のサンプルコードは、署名対象文字列を作成する方法の例を示しています。
StringBuilder strBuilderSign = new StringBuilder(); strBuilderSign.append(HTTPMethod); strBuilderSign.append("&"); strBuilderSign.append(percentEncode(urlPath)); strBuilderSign.append("&"); strBuilderSign.append(percentEncode(queryString)); stringToSign = strBuilderSign.toString();説明完全なサンプルコードの詳細については、「完全なサンプルコード」セクションの
createStringToSign関数を参照してください。次の署名対象文字列が作成されます。

署名を計算します。
HMAC-SHA1アルゴリズムとBase64を使用して、署名対象文字列のHMAC値を計算します。次に、計算されたHMAC値を
UTF-8でエンコードします。SHA1アルゴリズムを使用して、手順2で作成された署名対象文字列のHMAC値を計算します。 AccessKeyシークレットは、HMAC計算のキーとして使用されます。 AccessKeyシークレットの後にアンパサンド(
&)を追加する必要があります。計算された署名に対してURLエンコードを実行します。
次のサンプルコードは、署名を計算する方法の例を示しています。
signature = Base64( HMAC-SHA1(stringToSign, accessKeySecret + "&") ); // URL エンコードを実行します signature = percentEncode(signature)説明完全なサンプルコードの詳細については、「完全なサンプルコード」セクションの
sign関数を参照してください。次の署名が計算されます。
# 署名対象文字列の HMAC 値 AKIktdPUMCV12fTh667BLXeuCtg= # URL エンコードされた署名 AKIktdPUMCV12fTh667BLXeuCtg%3D署名が計算されたら、等号(
=)を使用して、Signatureパラメータのキーと値を接続します。次に、アンパサンド(&)を使用して、Signatureパラメータと手順1で取得した正規化されたクエリ文字列を接続します。その後、クライアントは署名付きHTTP GETリクエストをサーバーに送信してアクセストークンを取得できます。String queryStringWithSign = "Signature=" + signature + "&" + queryString;
クイックテスト
次のパラメータを使用して署名を計算し、計算された署名をテストします。
AccessKey IDとAccessKeyシークレットは実際のものではありません。タイムスタンプの期限が切れています。これらのパラメータに基づいて計算された署名を使用してアクセストークンを取得することはできません。これらのパラメータは、署名を計算してテストするためだけに使用されます。
AccessKeyId:
my_access_key_idAccessKeySecret:
my_access_key_secretTimestamp:
2019-04-18T08:32:31ZSignatureNonce:
b924c8c3-6d03-4c5d-ad36-d984d3116788
次のリクエストパラメータが使用されます。
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正規化されたクエリ文字列を作成します。
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署名対象文字列を作成します。

署名を計算して取得します。
hHq4yNsPitlfDJ2L0nQPdugdEzM= # URL エンコードされた署名 hHq4yNsPitlfDJ2L0nQPdugdEzM%3D正規化されたクエリ文字列に署名を追加します。
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-28HTTPリクエスト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手順5で取得したHTTPリクエストURLをブラウザのアドレスバーに入力するか、次のcurlコマンドを実行してアクセストークンを取得します。
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"
完全なサンプルコード
このセクションでは、JavaとPythonのサンプルコードを提供します。これらのプロトコルとサンプルコードに基づいて、他の言語でクライアントプログラムのコードを記述できます。
Java のデモ
次の依存関係を追加します。
<!-- 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>サンプルコード:
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); } } }Python のデモ
説明Python のバージョンは Python 3.4 以降である必要があります。
次のコマンドを実行して、Python HTTP ライブラリ 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))))