アクセストークンのリクエスト方法


アクセストークンのリクエスト方法

Amazon Device Messaging(ADM)を使用してアプリインスタンスにメッセージを送信するには、サーバー側で以下の準備が整っている必要があります。

  • アプリインスタンスの登録IDを取得して保存済みであること。詳細については、アプリの統合方法を参照してください。
  • OAuthクライアント認証情報と現在のアクセストークンが交換済みであること。プロセスについてはこのドキュメントで説明します。

メッセージの送信方法とADMのアーキテクチャについては、メッセージの送信方法Amazon Device Messaging(ADM)についてを参照してください。

クライアント認証情報とアクセストークン

アクセストークンを取得するために、開発者サーバーからADMサーバーにOAuthクライアント認証情報が渡されます。クライアント認証情報はAmazonから割り当てられ、アプリ固有の2つのデータ(client_id値とclient_secret値)で構成されています。開発者サーバーは同認証情報の両データをリクエスト内で使用して、ADMアクセストークンを取得します。クライアント認証情報の取得方法については、認証情報の取得方法を参照してください。

アクセストークンは、ADMに対して開発者サーバーの識別情報を認証して、メッセージを送信できるようにするための一時的なメタデータです。ADMを使用してメッセージを送信する場合、メッセージリクエストにアクセストークンを含める必要があります。サーバー側では、常に1つのアクセストークンのみが使用されますが、以前に取得したアクセストークンが有効期限切れになった際には新たに取得する必要があります。また、複数のサーバー間でアクセストークンを共有することもできますが、開発者サーバーごとに異なるアクセストークンを入手して、メッセージ送信時に個別にリクエスト、追跡、使用する方が便利です。

リクエスト形式

開発者サーバーは、ADMサーバーへのリクエスト呼び出しでクライアント認証情報を提供して、アクセストークンを取得します。初めてアクセストークンを取得する際や期限切れのために新たに取得する際も、同様のリクエストを行ってください。

アクセストークンの取得時は、開発者サーバー側でHTTPS接続を介してPOSTリクエストを発行します。リクエストは次のようになります。

POST /auth/O2/token HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=client_credentials&scope=messaging:push&client_id=(クライアントID)&client_secret=(クライアントシークレット)

リクエスト自体は、ヘッダーとメッセージ本文で構成されています。ヘッダーには、次のフィールドを含めてください。

フィールド 概要
Content-Type リソースのコンテンツタイプ。次の値になります:application/x-www-form-urlencoded Content-Type: application/x-www-form-urlencoded

メッセージ本文のコンテンツには、次のパラメーターを含む、URLエンコードされた文字列を指定します。

パラメーター 説明
grant_type 有効値:client_credentials grant_type=client_credentials
scope 有効値:messaging:push scope=messaging:push
client_id クライアント認証情報の「クライアント識別子」部分。 client_id=amzn1.iba-client.b2b360f8a77d457981625636121d6edf
client_secret クライアント認証情報の「クライアントシークレット」部分。 client_secret=c559965801308f2bb79ca787 b1dfc8deece8a2fd7d7618946cec1635d26dcbfb

レスポンス形式

ADMは、POSTリクエストメッセージを正常に受信して解釈した後、開発者サーバーに次のようなHTTPレスポンスメッセージを送信します。

X-Amzn-RequestId: d917ceac-2245-11e2-a270-0bc161cb589d
Content-Type: application/json

{
  "access_token":"Atc|MQEWYJxEnP3I1ND03ZzbY_NxQkA7Kn7Aioev_OfMRcyVQ4NxGzJMEaKJ8f0lSOiV-yW270o6fnkI",
  "expires_in":3600,
  "scope":"messaging:push",
  "token_type":"Bearer"
}

レスポンスのヘッダーには、次のフィールドが含まれます。

ヘッダー 説明
X-Amzn-RequestId リクエストを一意に識別するためにADMによって作成された値。万が一、ADMに問題が発生した場合は、Amazon側でこの値を用いてトラブルシューティングを行います。 X-Amzn-RequestId: d917ceac-2245-11e2-a270-0bc161cb589d
Content-Type リソースのコンテンツタイプ:application/json Content-Type: application/json

開発者サーバーがアクセストークンを正常にリクエストした場合、ステータスコード200のレスポンスが返されます。そのメッセージ本文には、アクセストークンとその存続期間(秒単位)の情報が含まれています。

パラメーター 説明
access_token すべてのエンキューリクエストに使用するアクセストークンです。 "access_token":"Atc|MQEWYJxEnP3I1ND03Zz..." (読みやすくするために短縮されています)
expires_in アクセストークンの存続時間(秒単位)です。たとえば、値が「3600」の場合、レスポンスの生成から1時間でアクセストークンが有効期限切れになります。 "expires_in":3600
token_type 発行されたトークンのタイプです。サポートされているトークンタイプの1つ。現時点では、「Bearer」トークンのみがサポートされています。 "token_type":"Bearer"
scope アクセストークンリクエストで指定された範囲です。値はmessaging:pushになります。 "scope":"messaging:push"

リクエストに失敗した場合は、ADMから200以外のエラーステータスコードが返されます。その場合、レスポンスメッセージのJSONObjectの本文に次のパラメーターが含まれている可能性があります。

  • reason: リクエストが受理されなかった理由。

アクセストークンリクエストに返される可能性のあるエラーステータスコードは、次のとおりです。

コード 説明
400 このレスポンスが返される理由:* コンテンツタイプが認証サーバーでサポートされていません(つまり、application/x-www-form-urlencodedではありません)。* リクエストに必須パラメーター(client_idclient_secretscopegrant-type)が含まれていません。* リクエストの形式に誤りがあります。* セキュリティプロファイルでADMが有効になっていません。認証情報の取得方法を参照してください。 INVALID_REQUEST
400 リクエストされた操作を行うパーミッションがクライアントにありません。 UNAUTHORIZED_CLIENT
400 認可タイプが認証サーバーでサポートされていません(つまり、client_credentialsではありません)。 UNSUPPORTED_GRANT_TYPE
400 リクエストされた範囲が無効です(つまり、messaging:pushではありません)。 INVALID_SCOPE
401 クライアントの認証に失敗しました。 INVALID_CLIENT
500 内部サーバーエラーが発生しました。リクエストした側はリクエストを再試行できます。 SERVER_ERROR
503 サーバーが一時的に利用できない状態になっています。リクエストした側は、レスポンスに含まれているRetry-Afterヘッダーに従って、後で再試行する必要があります。Retry-After値で有効な形式については、HTTP/1.1仕様のセクション14.37を参照してください。 SERVICE_UNAVAILABLE

トークンリクエストとレスポンス処理

次のコードサンプルは、開発者サーバーソフトウェアでアクセストークンリクエストを送信し、ADMサーバーのレスポンスを処理する方法を例示したものです。

/**
  * アクセストークンを取得するには、AmazonにHTTPSリクエストを行い、
  * client_idおよびclient_secretの値を含めます。
  */
public String getAuthToken(String clientId, String clientSecret) throws Exception
{
     // clientIDとclientSecretの値を含めて、リクエストの本文をエンコードします。
     String body = "grant_type="    + URLEncoder.encode("client_credentials", "UTF-8") + "&" +
                   "scope="         + URLEncoder.encode("messaging:push", "UTF-8")     + "&" +
                   "client_id="     + URLEncoder.encode(clientId, "UTF-8")             + "&" +
                   "client_secret=" + URLEncoder.encode(clientSecret, "UTF-8");

     // アクセストークンリクエストのベースURLを使用して、新しいURLオブジェクトを作成します。
     URL authUrl = new URL("https://api.amazon.com/auth/O2/token");

     // HTTPS接続を生成します。HTTP経由で接続することはできません。
     HttpsURLConnection con = (HttpsURLConnection) authUrl.openConnection();
     con.setDoOutput( true );
     con.setRequestMethod( "POST" );

     // Content-Typeヘッダーを設定します。
     con.setRequestProperty( "Content-Type" , "application/x-www-form-urlencoded" );
     con.setRequestProperty( "Charset" , "UTF-8" );
     // 接続点のエンコード済みパラメーターを送信します。
     OutputStream os = con.getOutputStream();
     os.write(body.getBytes( "UTF-8" ));
     os.flush();
     con.connect();

     // レスポンスをStringオブジェクトに変換します。
     String responseContent = parseResponse(con.getInputStream());

     // アクセストークンを保持する新しいJSONObjectを作成し、
     // レスポンスからトークンを抽出します。
     org.json. JSONObject parsedObject = new org.json.JSONObject(responseContent);
     String accessToken = parsedObject.getString("access_token");
     return accessToken;
}

private String parseResponse(InputStream in) throws Exception
{
     InputStreamReader inputStream = new InputStreamReader(in, "UTF-8" );
     BufferedReader buff = new BufferedReader(inputStream);

     StringBuilder sb = new StringBuilder();
     String line = buff.readLine();
     while (line != null )
     {
       sb.append(line);
       line = buff.readLine();
     }

     return sb.toString();
}