iOS用のLogin with Amazon SDK APIを使用する
AppDelegateの接続
プロジェクトで、UIApplicationDelegateプロトコルを処理するクラスにapplication:openURL:options:を実装します。デフォルトでは、これはAppDelegateクラスになります。Login with Amazonを使用してアプリにログインしたユーザーは、開発者が事前にアプリのプロパティリストに追加していたURLスキームに基づいて、Amazonログイン画面から元のアプリ画面にリダイレクトされます。このリダイレクトを処理するには、application:openURL:options:メソッドを実装する必要があり、URLが正常に処理された場合にYESを返します。
iOS用のLogin with Amazon SDKは、ライブラリ関数としてhandleOpenURL:sourceApplication:を提供します。これは、Amazonページから送信されるリダイレクトURLを処理します。SDKによってURLが正常に処理されると、YESが返されます。このメソッドをapplication:openURL:options:メソッド内で呼び出します。
このメソッドを呼び出すには、<LoginWithAmazon/LoginWithAmazon.h>をインポートする必要があります。
import <LoginWithAmazon/LoginWithAmazon.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)
url options:(NSDictionary<uiapplicationopenurloptionskey,id> *)options {
return [AMZNAuthorizationManager handleOpenURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]];
}
@end
ログインボタンの処理とプロファイルデータの取得
このセクションでは、authorize:withHandler: APIを呼び出してユーザーをログインする方法について説明します。これには、[Login with Amazon] ボタン用にonLoginButtonClicked:リスナーを作成することが含まれます。
-
iOSプロジェクトにLogin with Amazonを追加します。手順については、Login with Amazonプロジェクトを作成するを参照してください。
-
ソースファイルにLogin with Amazon APIをインポートします。
Login with Amazon APIをインポートするには、ソースファイルに次の#importステートメントを追加します。
#import <LoginWithAmazon/LoginWithAmazon.h> -
authorize:withHandler:をonLoginButtonClickedで呼び出します。「アプリに [Login with Amazon] ボタンを追加する」の手順を実行していれば、
onLoginButtonClicked:メソッドが [Login with Amazon] ボタンにリンクされているはずです。そのメソッドでauthorize:withHandler:を呼び出して、ユーザーにログインとアプリの認可を求める画面を表示します。この場合、ユーザーは次のいずれかの方法でサインインとリクエストされた情報への同意を行うことができます。
- 安全なコンテキストでウェブ表示に切り替える(デバイスにAmazonショッピングアプリがインストールされている場合)
- Safari View Controllerに切り替える(iOS 9以降)
- システムブラウザに切り替える(iOS 8以前)
最初の選択肢にある安全なコンテキストは、Amazonショッピングアプリをデバイスにインストールしている場合に使用できます。ユーザーがAmazonショッピングアプリにサインインしている場合、APIによってサインインのページはスキップされ、シングルサインオン(SSO)が実行されます。詳細については、iOSアプリのユーザーエクスペリエンスに関するページを参照してください。
authorize:withHandler:の最初のパラメーターはAMZNAuthorizeRequestオブジェクトで、アプリが認可をリクエストしているスコープを示します。スコープには、Login with Amazonに対してリクエストしているユーザーデータが含まれます。ユーザーが初めてアプリにログインするときに、開発者がリクエストして承認を求めているデータの一覧と一緒に提示されます。Login with Amazonは現在、次のスコープをサポートしています。
profile(ユーザーの名前、Eメールアドレス、AmazonアカウントIDへのアクセスを許可)、profile:user_id(ユーザーのAmazonアカウントIDのみへのアクセスを許可)、postal_code(Amazonアカウントに登録されているユーザーの郵便番号へのアクセスを許可)の3つです。AMZNProfileScopeで定義されるメソッドを使用してスコープオブジェクトを取得し、それをAMZNAuthorizeRequestオブジェクトに追加します。詳細については、以下のサンプルコードを参照してください。authorize:withHandler:の2番目のパラメーターはAMZNAuthorizationRequestHandlerです。これについては、次の手順で説明します。 -
AMZNAuthorizationRequestHandlerブロックオブジェクトを作成します。AMZNAuthorizationRequestHandlerはauthorize:withHandler:の呼び出しの結果を処理します。Objective-Cブロックの詳細については、developer.apple.comのWorking with Blocks(ブロックの使用)を参照してください。AMZNAuthorizationRequestHandlerの最初のパラメーターはAMZNAuthorizeResultオブジェクトです。ユーザーが認可されたら、AMZNAuthorizeResultにユーザーのプロファイルデータにアクセスするためのアクセストークンが返され、AMZNUserオブジェクトにユーザーのプロファイルデータが入ります。AMZNAuthorizationRequestHandlerの2番目のパラメーターは、userDidcancelと呼ばれるブール値です。このパラメーターは、ユーザーが次の操作をする場合に「true」に設定されます。- ログイン/認可中にSafari View Controllerを閉じる(iOS 9以降)
- AmazonショッピングアプリのWebViewでサインイン画面または同意画面を閉じる
- ログインをキャンセルするか認可を拒否する
AMZNAuthorizationRequestHandlerの3番目のパラメーターは、NSErrorオブジェクトです。これは、SDKや認可サーバーが原因でログイン/認可に失敗した場合にエラーの詳細を返します。- (IBAction)onLogInButtonClicked:(id)sender { // 認可リクエストを作成。 AMZNAuthorizeRequest *request = [[AMZNAuthorizeRequest alloc] init]; request.scopes = [NSArray arrayWithObjects: // [AMZNProfileScope userID], [AMZNProfileScope profile], [AMZNProfileScope postalCode]]; // Login with Amazon SDKにauthorize呼び出しを実行。 [[AMZNAuthorizationManager sharedManager] authorize:request withHandler:^(AMZNAuthorizeResult *result, BOOL userDidCancel, NSError *error) { if (error) { // SDKまたは認可サーバーからのエラーを処理。 } else if (userDidCancel) { // ユーザーがログインをキャンセルする際に生じたエラーを処理。 } else { // 認証に成功。 // アクセストークンとユーザープロファイルデータを取得。 NSString *accessToken = result.token; AMZNUser *user = result.user; NSString *userID = user.userID; } }]; }
ユーザープロファイルデータの取得
ユーザーがアプリにログインして認可を受けている限り、開発者はいつでもそのユーザーのプロファイルデータを取得できます。このセクションでは、AMZNUserクラスのfetch:メソッドを使用して、認可済みユーザーの最新のプロファイルデータを取得する方法について説明します。取得できるプロファイルデータは、authorize呼び出しで示されるスコープに基づきます。
-
AMZNUser fetch:を呼び出します。このメソッドは、
AMZNUserFetchRequestHandlerブロックオブジェクトを介してプロファイルデータを取得します。AMZNUserRequestHandlerの最初のパラメーターは、AMZNUserオブジェクトです。AMZNUserオブジェクトには、リクエストされたスコープに応じて、userID、name、email、postalCodeを含めることができます。[AMZNUser fetch:^(AMZNUser *user, NSError *error) { if (error) { // SDKからのエラー、またはアプリの認可を行ったユーザーがいない。 } else if (user) { NSString *userID = user.userID; //NSString *name = user.name; //NSString *email = user.email; //NSString *postalCode = user.postalCode; } }];
起動時のユーザーログインの確認
アプリにログインしたユーザーが、アプリをいったん終了した後で再度アプリを起動させた場合、アプリは引き続きデータを取得できます。ユーザーが自動的にログアウトされることはありません。起動時にアプリが認可されていれば、ユーザーにログイン後の状態を表示できます。このセクションではauthorize:withHandler:を使用して、アプリがまだ認可されているかどうかを確認する方法について説明します。
-
AMZNAuthorizeRequestオブジェクトを作成し、アプリが認可をリクエストしているユーザーデータを示すスコープを指定します。スコープの詳細については、上記の「ログインボタンの処理とプロファイルデータの取得」を参照してください。 -
AMZNAuthorizeRequest.interactiveStrategyをAMZNInteractiveStrategyNeverに設定します。AMZNAuthorizeRequestは、ユーザーのログインを求めるさまざまな戦略をサポートしています。AMZNInteractiveStrategyAuto(デフォルト): SDKはローカルに保存された認可グラントがあるかどうかを過去のauthorize:withHandler:レスポンスから探します。リクエストされたスコープをすべて含む有効な認可グラントがあれば、SDKはAMZNAuthorizationRequestHandlerを介して成功のレスポンスを返します。ユーザーにログインを求める画面は表示しません。有効な認可グラントがなければ、ユーザーにログインを求めます。AMZNInteractiveStrategyAlways:過去にアプリの使用が許可されているかどうかにかかわらず、常にユーザーにログインを求めます。ユーザーにログインを求める際に、SDKはローカルにキャッシュされているアプリの認可グラントをすべて削除します。AMZNInteractiveStrategyNever:SDKはローカルに保存された認可グラントがあるかどうかを過去のauthorize:withHandlerレスポンスから探します。リクエストされたスコープをすべて含む有効な認可グラントがあれば、SDKはアクセストークンとユーザープロファイルデータが含まれるAMZNAuthorizeResultオブジェクトを返します。有効な認可グラントがなければ、AMZNAuthorizationRequestHandlerを介してNSErrorオブジェクトを返します。
// 認可リクエストを作成。 AMZNAuthorizeRequest *request = [[AMZNAuthorizeRequest alloc] init]; request.scopes = [NSArray arrayWithObjects: // [AMZNProfileScope userID], [AMZNProfileScope profile], [AMZNProfileScope postalCode]]; request.interactiveStrategy = AMZNInteractiveStrategyNever; [[AMZNAuthorizationManager sharedManager] authorize:request withHandler:^(AMZNAuthorizeResult *result, BOOL userDidCancel, NSError *error) { if (error) { // SDKからのエラーで、このユーザーはリクエストしたスコープに対し過去にアプリへの権限を与えられていないことを示す。 } else { // このユーザーは過去にアプリへの権限が与えられていた。 // アクセストークンとユーザープロファイルデータを取得。 NSString *accessToken = result.token; AMZNUser *user = result.user; NSString *userID = user.userID; } }];
認可データの消去とユーザーのログアウト
このセクションでは、signOutメソッドを使用して、ユーザーの認可データをAMZNMobileLibローカルデータストアと認可サーバーの両方から消去する方法について説明します(iOS用のLogin with Amazonバージョン3.1.0で、AIMobileLibの名前がAMZNMobileLibに変更されました)。アプリがプロファイルデータを取得するには、ユーザーが再度ログインする必要があります。このメソッドを使用するのは、ユーザーをログアウトする場合、またはアプリのログイン問題をトラブルシューティングする場合です。
-
ログアウトのメカニズムを実装します。
ユーザーがログインに成功したら、ログアウトのメカニズムを提供してユーザーがプロファイルデータと過去の認可済みのスコープを消去できるようにします。ログアウトのメカニズムとして、ハイパーリンク、ボタン、メニューアイテムを使用できます。
-
signOut:を呼び出します。signOut:をログアウトハンドラーで呼び出し、ローカルデータストアからユーザーの認可データ(アクセストークン、プロファイル)を削除して、サーバーから認証状態を消去します。signOutの入力パラメーターは、AMZNAuthorizationRequestHandlerブロックオブジェクトです。そのブロックはNSErrorオブジェクトを検出して処理します。このオブジェクトはsignOut:が失敗すると返されます。[[AMZNAuthorizationManager sharedManager] signOut:^(NSError * _Nullable error) { if (!error) { // SDKまたはLogin with Amazon認可サーバーからのエラー。 } }];
統合のテスト
iOSデバイスまたはシミュレーターでアプリを起動し、Amazon.comの認証情報を使用してログインできることを確認します。
authorizeUserForScopesリクエストに対して表示されたり、「Unknown Error Code」がclearAuthorizationStateリクエストに対して表示されたりする場合があります。これは、SDKがキーチェーンにアクセスするときに発生するAppleの既知のバグです。Appleがバグを解決するまで、アプリのターゲットの [Capabilities] タブでアプリの [Keychain Sharing] を有効にすることで問題に対応してください。このバグの影響を受けるのはシミュレーターのみです。実際のiOS10デバイスでテストをする場合は、こうした回避策は必要ありません。
