すべてのプロダクト
Search
ドキュメントセンター

:API操作の呼び出しによるアクセストークンの取得

最終更新日:Mar 14, 2025

このトピックでは、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リクエストを検証する方法を示しています。

  1. クライアントは、HTTPリクエストパラメータとリクエストボディを含むAPIリクエストのコンテンツに基づいて文字列署名を生成します。

  2. クライアントは、Alibaba CloudアカウントのAccessKey IDとAccessKeyシークレットを使用して、手順1で生成された署名文字列を暗号化します。次に、クライアントはこのAPIリクエストのデジタル署名を取得します。

  3. クライアントは、署名付きAPIリクエストをサーバーに送信します。

  4. サーバーはAPIリクエストを受信した後、手順12を繰り返して、APIリクエストの予期されるデジタル署名を計算します。サーバーは、バックエンドからAPIリクエストで使用されるAccessKey IDとAccessKeyシークレットを取得できます。

  5. サーバーは、予期されるデジタル署名とクライアントから送信されたデジタル署名を比較します。署名が同じであれば、リクエストはセキュリティ検証に合格します。署名が異なれば、サーバーはAPIリクエストを拒否します。

APIリクエストの署名文字列を生成する

  1. 正規化されたクエリ文字列を作成します。

    Signatureパラメータを含めずに、HTTPリクエストパラメータに基づいて正規化されたクエリ文字列を作成します。正規化されたクエリ文字列を作成するには、次の手順を実行します。

    1. リクエストパラメータをアルファベット順にソートします。パラメータ名は大文字と小文字が区別されます。

    2. パラメータをエンコードします。ソートされたリクエストパラメータを正規化します。

      次のルールに基づいて、リクエストパラメータの名前と値を 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 をチルダ(~)に置き換えて、必要な文字列を取得できます。

    3. 等号(=)を使用して、URLエンコードされた各リクエストパラメータの名前と値を接続します。例:percentEncode (parameter key) + "=" + percentEncode (parameter value)

    4. アンパサンド(&)を使用して、手順cで生成されたURLエンコードされたリクエストパラメータのキーと値のペアを接続します。例:Action=CreateToken&Format=JSON

      説明

      正規化されたクエリ文字列の最初のパラメータ名の前にアンパサンド(&)を追加しないでください。

    5. 正規化されたクエリ文字列を返します。

    サンプルコード:

    // パラメータキーをソートします。
    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

  2. 署名対象文字列を作成します。

    署名対象文字列は、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 関数を参照してください。

    次の署名対象文字列が作成されます。

    String-to-sign

  3. 署名を計算します。

    • 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_id

  • AccessKeySecret:

    my_access_key_secret

  • Timestamp:

    2019-04-18T08:32:31Z

  • SignatureNonce:

    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
  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-02-28

  2. 署名対象文字列を作成します。

    String-to-sign

  3. 署名を計算して取得します。

    hHq4yNsPitlfDJ2L0nQPdugdEzM=
    # URL エンコードされた署名
    hHq4yNsPitlfDJ2L0nQPdugdEzM%3D

  4. 正規化されたクエリ文字列に署名を追加します。

    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を取得します。

    http://nlsmeta.ap-southeast-1.aliyuncs.com/?Signature=hHq4yNsPitlfDJ2L0nQPdugdEzM%3D&AccessKeyId=my_access_key_id&Action=CreateToken&Format=JSON&RegionId=ap-southeast-1&SignatureMethod=HMAC-SHA1&SignatureNonce=b924c8c3-6d03-4c5d-ad36-d984d3116788&SignatureVersion=1.0&Timestamp=2019-04-18T08%3A32%3A31Z&Version=2019-02-28

  6. 手順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))))