AndroidでLogin with Amazon SDKを使用する

Login with Amazon SDK for Androidを使ってLogin with Amazonの許可コード、クライアントID、リダイレクトURIを対象デバイスに渡すには、以下の手順に従ってください。対象デバイスは、そのデータを使って、DRSの呼び出しに必要なrefreshaccess token を取得できます。サンプルコード全文は、Amazon Dash GitHubリポジトリで入手できます。

LwAバージョンに関して

このドキュメントでは、LwAバージョン3.0.0を使用しています。LwAのバージョンは、Android 3.x用のLogin with Amazon SDKへの移行ガイドの手順に従って確認できます。

上記手順におけるバージョンの確認方法の出力は:

LWA_VERSION = "3.0.0";

Androidにおける許可コードの取得とDRSの呼び出し

  1. Login with AmazonのGetting Started for Androidに移動し、手順1~5を実行します。
ティザーページ

上記の手順5において、"Login with Amazon"ボタンの追加方法が記載されています。ボタンを追加するだけではなく、ティザーページのガイドラインに基づいてページをデザインしてください。
  1. セキュリティプロファイルコンソールから新しいAPIキーを取得します。セキュリティプロファイルがない場合は、LwAセキュリティプロファイルの作成ガイドの手順に従って作成してください。
  2. [Security Profile Management] で、セキュリティプロファイルの [Android/Kindle Settings] を選択します。

  3. 必須フィールドに入力してアプリケーションを登録します。
  4. [Key]列の[Show]をクリックしてAPIキーを表示します。

  5. アプリケーションのapi_key.txtファイルにAPIキーをコピーします。
  6. 次のステートメントを追加してLwA APIをソースファイルにインポートします。

     import com.amazon.identity.auth.device.AuthError;
     import com.amazon.identity.auth.device.api.authorization.AuthCancellation;
     import com.amazon.identity.auth.device.api.authorization.AuthorizationManager;
     import com.amazon.identity.auth.device.api.authorization.AuthorizeListener;
     import com.amazon.identity.auth.device.api.authorization.AuthorizeRequest;
     import com.amazon.identity.auth.device.api.authorization.AuthorizeResult;
     import com.amazon.identity.auth.device.api.authorization.Scope;
     import com.amazon.identity.auth.device.api.authorization.ScopeFactory;
     import com.amazon.identity.auth.device.api.workflow.RequestContext;
    
  7. RequestContextオブジェクトをクラス変数として宣言し、onCreate()メソッド内で初期化します。

     private RequestContext requestContext;
    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      requestContext = RequestContext.create(this);
     }
    
  8. 新しいAuthorizeListenerをこのRequestContextオブジェクトに登録します。

     requestContext.registerListener(new AuthorizeListener() {
    
      /* 認証が成功した場合 */
      @Override
      public void onSuccess(final AuthorizeResult authorizeResult) {
       runOnUiThread(new Runnable() {
        @Override
        public void run() {
         Log.d(TAG, authorizeResult.getRedirectURI());
         Log.d(TAG, authorizeResult.getAuthorizationCode());
         Log.d(TAG, authorizeResult.getClientId());
        }
       });
      }
    
      /* 認証時何らかのエラーが発生した場合 */
      @Override
      public void onError(AuthError authError) {
       runOnUiThread(new Runnable() {
        @Override
        public void run() {
         Log.e(TAG, "Error during authorization. Please try again.");
        }
       });
      }
    
      /* 認証完了前にキャンセルされた場合 */
      @Override
      public void onCancel(AuthCancellation authCancellation) {
       runOnUiThread(new Runnable() {
        @Override
        public void run() {
         Log.i(TAG, "Authorization cancelled.");
        }
       });
      }
     });
    

    それぞれのログインシナリオに対応するコードをonSuccess()onError()onCancel()の各メソッドに記述する必要があります。

  9. 次のコードをonResume()メソッドに追加します。

    @Override
    protected void onResume() {
     super.onResume();
     requestContext.onResume();
    }
    
  10. 許可を実行するために、次のコード行をアプリケーションに追加します。

    AuthorizationManager.authorize(
     new AuthorizeRequest.Builder(requestContext)
     .addScopes(YOUR-LOGIN-SCOPE)
     .forGrantType(AuthorizeRequest.GrantType.AUTHORIZATION_CODE)
     // コードチャレンジと、コードチャレンジの方法("plain"または"S256")を設定
     .withProofKeyParameters(YOUR_CODE_CHALLENGE,
      YOUR_CODE_CHALLENGE_METHOD)
     .build()
    )
    

    YOUR_CODE_CHALLENGE および YOUR_CODE_CHALLENGE_METHOD の詳細は、こちらの前提条件をご覧ください。ログインボタンの場合は次のようになります。

    /**
    * すべてのUI要素の初期化
    */
    private void initializeUI() {
        mLoginButton = findViewById(R.id.login_with_amazon);
        mLoginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Scope scope = getScope();
                if (scope != null) {
                    AuthorizationManager.authorize(
                            new AuthorizeRequest.Builder(requestContext)
                                    .addScopes(scope)
                                    .forGrantType(AuthorizeRequest.GrantType.AUTHORIZATION_CODE)
                                    // コードチャレンジと、コードチャレンジの方法("plain"または"S256")を設定
                                    .withProofKeyParameters(YOUR_CODE_CHALLENGE, YOUR_CODE_CHALLENGE_METHOD)
                                    .build()
                    );
                }
            }
    
        });
    }
    
    /**
    * Login Scopeの取得
    *
    * @return Scope.
    */
    private Scope getScope() {
      //YOUR_DEVICE_MODEL_NAME - セルフサービスポータルから取得したデバイスのmodel ID
      //YOUR_DEVICE_SERIAL_NUMBER – DRSへ登録するデバイスのシリアル番号。アルファベットと数字[A-Za-z0-9]で50文字以内
      //IS_THIS_A_TEST_DEVICE – テストデバイスかどうかをあらわすフラグ。テスト時にはtrueを、製品時にはfalseを設定する。テストデバイスは実際の発注ができません。
      // SHOULD_INCLUDE_NON_LIVE – trueの場合、DRS認定されていないデバイスであってもデバイス登録が可能になります。認定前のテストで使います。
        final String scopeDataString = "{\"device_model\":\"" + YOUR_DEVICE_MODEL_NAME +
                "\", \"serial\":\"" + YOUR_DEVICE_SERIAL_NUMBER +
                "\", \"is_test_device\":\"" + IS_THIS_A_TEST_DEVICE +
                "\", \"should_include_non_live\":\"" + SHOULD_INCLUDE_NON_LIVE +
                "\"}";
        JSONObject scopeData;
        try {
            scopeData = new JSONObject(scopeDataString);
            return ScopeFactory.scopeNamed("dash:replenish", scopeData);
        } catch (JSONException e) {
            Log.e(TAG, "Error during scope data JSON object creation", e);
        }
        return null;
    }
    

    access tokenrefresh token を取得するPOSTリクエストの呼び出しに必要な準備は、以上で完了です。

    以降のステップは、この呼び出しの確認をおこないます。この呼び出しは、モバイルアプリケーションやDRS対応製品、またはバックエンドソリューションから行うことができます(本ドキュメントでは、DRS対応製品上で呼び出すケースで記載しております)

  11. ログインに成功すると、AuthorizeListener onSuccess()が呼び出されます。許可コード、クライアントID、リダイレクトURIを取得し、SSLを使って安全に対象デバイスに転送する必要があります。
  12. 許可コード、クライアントID、リダイレクトURIがデバイス上に受信されると、デバイスは許可コードを用いてLwAを呼び出し、アクセストークンリフレッシュトークン を取得できるようになります。

許可コードを用いたリフレッシュトークンとアクセストークンの取得

呼び出しに際し、デバイスは下記パラメータを用いたPOSTリクエストをhttps://api.amazon.com/auth/O2/tokenに対して行います:

HTTP Headerパラメータ

  • Content-Type:application/x-www-form-urlencoded

HTTP Bodyパラメータ

  • grant_type:authorization_code
  • code:Androidアプリケーションから受け取った許可コードの文字列。
  • redirect_uri:Androidアプリケーションから受け取ったリダイレクトURIの文字列。
  • client_id:Androidアプリケーションから受け取ったクライアントIDの文字列。
  • code_verifier:デバイスにより最初に生成されたコードベリファイア文字列。

サンプルリクエスト:

 POST /auth/o2/token HTTP/1.1
 Host:api.amazon.com
 Content-Type:application/x-www-form-urlencoded
 Cache-Control:no-cache
 code=YOUR-AUTHORIZATION-CODE&client_id=YOUR-CLIENT-ID&redirect_uri=YOUR-REDIRECT-URI&code_verifier=YOUR-CODE-VERIFIER&grant_type=authorization_code
 curl –X POST –d 'code=YOUR-AUTHORIZATION-CODE&client_id=YOUR-CLIENT-ID&redirect_uri=YOUR-REDIRECT-URI&code_verifier=YOUR-CODE-VERIFIER&grant_type=authorization_code' https://api.amazon.com/auth/O2/token

レスポンスは下記の値を含みます:

  • access_token:アクセストークン文字列
  • refresh_token:リフレッシュトークン文字列
  • token_type:トークンタイプ文字列
  • expires_in:アクセストークンの有効時間(秒)

サンプルレスポンス:

 HTTP/1.1 200 OK

 {
    "access_token": "Atza|IQEBLjAsAhRBejiZKPfn5HO2562GBt26qt23EA...",
    "expires_in": 3600,
    "refresh_token": "Atzr|IQEBLzAtAhUAibmh-1N0EsdqwqwdqdasdvferrE...",
    "token_type": "bearer"
 }

新規リフレッシュトークン・アクセストークンのリクエスト

アクセストークン は1時間有効です。アクセストークンが無効になった、あるいは無効になりそうな場合、リフレッシュトークン を用いて、新たなアクセストークンを取得できます。

  • 次のパラメータを用いて、POSTリクエストをhttps://api.amazon.com/auth/o2/tokenに対して行います。

HTTP Headerパラメータ

  • Content-Type:application/x-www-form-urlencoded

HTTP Bodyパラメータ

  • grant_type:refresh_token
  • refresh_token:新規アクセストークンをリクエストするためのリフレッシュトークン。
  • client_id:iOSアプリから取得するクライアントID文字列。
  • client_secret:セキュリティプロファイルのクライアントシークレット。この情報はLogin With Amazonで確認してください。

サンプルリクエスト

POST /auth/o2/token HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
grant_type=refresh_token&refresh_token=Atzr|CIQEBLzAtAhUAibmh-1N0E&client_id=amzn1.application-oa2-
client.b91a...&client_secret=6963038c1c2063c33ab9eedc...

サンプルレスポンス

HTTP/1.1 200 OK
{
   "access_token": "Atza|IQEBLjAsAhQ3yD47Jkj09BfU_qgNk4...",
   "expires_in": 3600,
   "refresh_token": "Atzr|IQEBLzAtAhUAibmh-1N0EVztZJofMx...",
   "token_type": "bearer"
}

次のステップ

次に、他のアプリでのLwAの実装について説明します。

作成したいアプリ ドキュメント
ネイティブAndroidアプリ AndroidでLogin with Amazon SDKを使用する
ネイティブiOSアプリ iOSでLogin with Amazon SDKを使用する
Webアプリ、およびCordovaのようなハイブリッドアプリ LwA Web APIの使用

すでにLwAを実装している場合、APIの概要にお進みいただけます。