AWS の開始方法
iOS アプリケーションを構築する
AWS Amplify を使用してシンプルな iOS アプリケーションを作成する
モジュール 3: 認証を追加する
このモジュールでは、Amplify CLI とライブラリを使用して、認証を設定し、アプリに追加します。
はじめに
次に追加する機能はユーザー認証です。このモジュールでは、マネージド型のユーザー ID プロバイダーである Amazon Cognito を利用して、Amplify CLI とライブラリでユーザーを認証する方法を学びます。
また、Cognito でホストされるユーザーインターフェイスを使用してユーザー認証フロー全体を表示する方法を学び、ユーザーが数行のコードでサインアップ、サインイン、パスワードのリセットを行えるようにします。
「ホストされたユーザーインタフェイス」を使用するということは、アプリケーションで Cognito のウェブページを利用して、サインインとサインアップのユーザーインタフェイスフローを行うということです。アプリケーションのユーザーは、Cognito でホストされるウェブページにリダイレクトされ、サインイン後にアプリにリダイレクトされます。当然、Cognito と Amplify もネイティブ UI をサポートします。カスタム認証 UI の詳細については、こちらのワークショップ手順を参照してください。
学習内容
- 認証サービスを作成してデプロイする
- Cognito でホストされる UI 認証を含めるように iOS アプリを設定する
主要な概念
Amplify ライブラリ – Amplify ライブラリにより、ウェブまたはモバイルアプリケーションから AWS のサービスを操作できます。
認証 – ソフトウェアでは、認証は、認証サービスまたは API を使用してユーザーの ID を確認および管理するプロセスです。
所要時間
10 分
使用するサービス
実装
-
認証サービスを作成する
認証サービスを作成するには、ターミナルを開いてこのコマンドを実行します。
amplify add auth ? Do you want to use the default authentication and security configuration? Select Default configuration with Social Provider and press enter ? How do you want users to be able to sign in? Select the default Username and press enter ? Do you want to configure advanced settings? Select the default No, I am done and press enter ? What domain name prefix do you want to use? Select the default and press enter Enter your redirect signin URI: type gettingstarted:// and press enter ? Do you want to add another redirect signin URI? Select the default N and press enter Enter your redirect signout URI: type gettingstarted:// and press enter ? Do you want to add another redirect signout URI? Select the default N and press enter ? Select the social providers you want to configure for your user pool: do not select any provider and press enter
設定が成功すると、次のメッセージが表示されます (リソースの正確な名前は異なります)。
Successfully added resource iosgettingstartedfc5a4717 locally
-
認証サービスをデプロイする
認証サービスがローカルで設定されたので、認証サービスをクラウドにデプロイできます。ターミナルのプロジェクトディレクトリでこのコマンドを実行します。
amplify push # press Y when asked to continue
しばらくすると、次のメッセージが表示されます。
✔ All resources are updated in the cloud Hosted UI Endpoint: https://iosgettingstarted-dev.auth.eu-central-1.amazoncognito.com/ Test Your Hosted UI Endpoint: https://iosgettingstarted-dev.auth.eu-central-1.amazoncognito.com/login?response_type=code&client_id=1234567890&redirect_uri=gettingstarted://
-
Amplify 認証ライブラリをプロジェクトに追加する
コードに進む前に、Amplify 認証ライブラリをプロジェクトの依存関係に追加します。Podfile を開き、AmplifyPlugins/AWSCognitoAuthPlugin という行を追加するか、次のファイル全体をコピーして貼り付けます。
# you need at least version 13.0 for this tutorial, more recent versions are valid too platform :ios, '13.0' target 'getting started' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! # Pods for getting started pod 'Amplify', '~> 1.0' # required amplify dependency pod 'Amplify/Tools', '~> 1.0' # allows to call amplify CLI from within Xcode pod 'AmplifyPlugins/AWSCognitoAuthPlugin', '~> 1.0' # support for Cognito user authentication end
ターミナルでこのコマンドを実行します。
pod install
このコマンドが完了するまでに数秒かかります。次のように表示されます (実際のバージョン番号は異なる場合があります)。
Analyzing dependencies Downloading dependencies Installing AWSAuthCore (2.14.1) Installing AWSCognitoIdentityProvider (2.14.1) Installing AWSCognitoIdentityProviderASF (1.0.1) Installing AWSCore (2.14.1) Installing AWSMobileClient (2.14.1) Installing AWSPluginsCore (1.0.4) Installing AmplifyPlugins (1.0.4) Generating Pods project Integrating client project Pod installation complete! There are 3 dependencies from the Podfile and 8 total pods installed.
-
Amplify 認証ライブラリを実行時に設定する
Xcode に戻り、バックエンド.swift ファイルを開きます。バックエンドクラスで、
- AmplifyPlugins のインポートステートメントを追加します
- 前のセクションで追加した Amplify 初期化コードに行を追加します
コードのブロックが完成すると、以下のようになります。
// at the top of the file import AmplifyPlugins private init () { // initialize amplify do { try Amplify.add(plugin: AWSCognitoAuthPlugin()) try Amplify.configure() print("Initialized Amplify") } catch { print("Could not initialize Amplify: \(error)") } }
すべてが想定どおりに動作することを検証するには、プロジェクトをビルドします。[Product (製品)] メニューをクリックして [Build (構築)] を選択するか、または ⌘B を押します。操作エラーがないようにします。
-
認証を実行時にトリガーします
残りのコードを変更すると、ユーザーのステータスを追跡できます (サインインの有無)。また、ユーザーがサインインしていない場合に、サインイン/サインアップのユーザーインターフェイスをトリガーします。
a.サインインとサインアウトのコードを追加バックエンドクラスの任意の場所に次の 3 つのメソッドを追加します。
// MARK: - User Authentication // signin with Cognito web user interface public func signIn() { _ = Amplify.Auth.signInWithWebUI(presentationAnchor: UIApplication.shared.windows.first!) { result in switch result { case .success(_): print("Sign in succeeded") case .failure(let error): print("Sign in failed \(error)") } } } // signout public func signOut() { _ = Amplify.Auth.signOut() { (result) in switch result { case .success: print("Successfully signed out") case .failure(let error): print("Sign out failed with error \(error)") } } } // change our internal state, this triggers an UI update on the main thread func updateUserData(withSignInStatus status : Bool) { DispatchQueue.main.async() { let userData : UserData = .shared userData.isSignedIn = status } }
b.認証ハブのリスナーを追加
認証ステータスの変更を追跡するには、Amplify によって送信される認証イベントにサブスクライブするためのコードを追加します。ハブは Backend.init() メソッドで初期化します。
認証イベントを受信したら、updateUserData() メソッドを呼び出します。このメソッドによって UserData オブジェクトの同期が維持されます。UserData.isSignedIn プロパティは @Published です。つまり、値が変更されるとユーザーインタフェイスが自動的に更新されます。
また、アプリケーションの起動時に以前の認証ステータスを確認するコードも追加します。アプリケーションが起動すると、Cognito セッションがすでに存在するかどうかを確認し、それに応じて UI を更新します。
Backend.init() で、Amplify の初期化後に次のコードを追加します。
// in private init() function // listen to auth events. // see https://github.com/aws-amplify/amplify-ios/blob/master/Amplify/Categories/Auth/Models/AuthEventName.swift _ = Amplify.Hub.listen(to: .auth) { (payload) in switch payload.eventName { case HubPayload.EventName.Auth.signedIn: print("==HUB== User signed In, update UI") self.updateUserData(withSignInStatus: true) case HubPayload.EventName.Auth.signedOut: print("==HUB== User signed Out, update UI") self.updateUserData(withSignInStatus: false) case HubPayload.EventName.Auth.sessionExpired: print("==HUB== Session expired, show sign in UI") self.updateUserData(withSignInStatus: false) default: //print("==HUB== \(payload)") break } } // let's check if user is signedIn or not _ = Amplify.Auth.fetchAuthSession { (result) in do { let session = try result.get() // let's update UserData and the UI self.updateUserData(withSignInStatus: session.isSignedIn) } catch { print("Fetch auth session failed with error - \(error)") } }
c.ユーザーインターフェイスコードを更新する
コードの最後の変更はユーザーインターフェイスに関連しています。ContentView に ZStack を追加します。UserData.isSignedIn の値に応じて UI には SigninButton ビューまたはメインリストビューが表示されます。
ContentView.swift を開き、ContentView struct 内で次のように本文を置き換えます。
var body: some View { ZStack { if (userData.isSignedIn) { NavigationView { List { ForEach(userData.notes) { note in ListRow(note: note) } } .navigationBarTitle(Text("Notes")) .navigationBarItems(leading: SignOutButton()) } } else { SignInButton() } } }
同じファイルで、次のように SignInButton ビューと SignOutButton ビューを追加します。
struct SignInButton: View { var body: some View { Button(action: { Backend.shared.signIn() }){ HStack { Image(systemName: "person.fill") .scaleEffect(1.5) .padding() Text("Sign In") .font(.largeTitle) } .padding() .foregroundColor(.white) .background(Color.green) .cornerRadius(30) } } } struct SignOutButton : View { var body: some View { Button(action: { Backend.shared.signOut() }) { Text("Sign Out") } } }
すべてが想定どおりに動作することを検証するには、プロジェクトをビルドします。[Product (製品)] メニューをクリックして [Build (構築)] を選択するか、または ⌘B を押します。操作エラーがないようにします。
d.Info.plist を更新
最後に、Cognito でホストされるユーザーインターフェイスによって提供されるウェブ認証シーケンスの最後でアプリが起動されるか確認する必要があります。gettingstarted URI スキームをアプリの Info.plist ファイルに追加します。
Xcode で Info.plist ファイルを選択し、右クリックしてから、[Open As (As を開く)]、[Source Code (ソースコード)] の順に選択します。
次の <key> 要素と <array> 要素を 一番上の <dict> 要素の中に追加します。
<plist version="1.0"> <dict> <!-- YOUR OTHER PLIST ENTRIES HERE --> <!-- ADD AN ENTRY TO CFBundleURLTypes for Cognito Auth --> <!-- IF YOU DO NOT HAVE CFBundleURLTypes, YOU CAN COPY THE WHOLE BLOCK BELOW --> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>gettingstarted</string> </array> </dict> </array> <!-- ... --> </dict>
e.ビルドとテスト
すべてが想定どおりに動作することを検証するには、プロジェクトをビルドします。[Product (製品)] メニューをクリックして [Run (実行)] を選択するか、または ⌘R を押します。操作エラーがないようにします。アプリは [Sign In (サインイン)] ボタンをクリックすると起動します。
サインアップの全体的な流れは次のとおりです。