サインイン
Amplify は、Amplify Auth などのバックエンドリソースと対話できるクライアントライブラリを提供しています。
signIn API の使用
func signIn(username: String, password: String) async { do { let signInResult = try await Amplify.Auth.signIn( username: username, password: password ) if signInResult.isSignedIn { print("Sign in succeeded") } } catch let error as AuthError { print("Sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}func signIn(username: String, password: String) -> AnyCancellable { Amplify.Publisher.create { try await Amplify.Auth.signIn( username: username, password: password ) }.sink { if case let .failure(authError) = $0 { print("Sign in failed \(authError)") } } receiveValue: { signInResult in if signInResult.isSignedIn { print("Sign in succeeded") } }}signIn API のレスポンスには nextStep プロパティが含まれており、さらなるアクションが必要かどうかを判断するために使用できます。次のステップが返される可能性があります:
| 次のステップ | 説明 |
|---|---|
confirmSignInWithNewPassword | ユーザーは一時パスワードで作成されており、新しいパスワードを設定する必要があります。confirmSignIn でプロセスを完了してください。 |
confirmSignInWithCustomChallenge | サインインはカスタムチャレンジレスポンスで確認する必要があります。confirmSignIn でプロセスを完了してください。 |
confirmSignInWithTOTPCode | サインインはユーザーからの TOTP コードで確認する必要があります。confirmSignIn でプロセスを完了してください。 |
confirmSignInWithSMSMFACode | サインインはユーザーからの SMS コードで確認する必要があります。confirmSignIn でプロセスを完了してください。 |
confirmSignInWithOTP | サインインはユーザーからのコード(SMS またはメールで送信)で確認する必要があります。confirmSignIn でプロセスを完了してください。 |
confirmSignInWithPassword | ユーザーは新しいパスワードを設定する必要があります。confirmSignIn でプロセスを完了してください。 |
continueSignInWithFirstFactorSelection | ユーザーは第一要素認証の優先モードを選択する必要があります。confirmSignIn でプロセスを完了してください。 |
continueSignInWithMFASelection | ユーザーはサインイン前に MFA 確認のモードを選択する必要があります。confirmSignIn でプロセスを完了してください。 |
continueSignInWithMFASetupSelection | ユーザーはセットアップする MFA 確認のモードを選択する必要があります。confirmSignIn に MFAType.email.challengeResponse または MFAType.totp.challengeResponse を渡してプロセスを完了してください。 |
continueSignInWithTOTPSetup | TOTP セットアッププロセスを続行する必要があります。confirmSignIn でプロセスを完了してください。 |
continueSignInWithEmailMFASetup | EMAIL セットアッププロセスを続行する必要があります。有効なメールアドレスを confirmSignIn に渡してプロセスを完了してください。 |
resetPassword | ユーザーは resetPassword を使用してパスワードをリセットする必要があります。 |
confirmSignUp | ユーザーはサインアップフローを完全に完了しておらず、confirmSignUp で確認する必要があります。 |
done | サインインプロセスが完了しました。 |
返される可能性がある MFA ステップの処理の詳細については、多要素認証を参照してください。
func confirmSignIn() async { do { let signInResult = try await Amplify.Auth.confirmSignIn(challengeResponse: "<confirmation code received via SMS>") print("Confirm sign in succeeded. Next step: \(signInResult.nextStep)") } catch let error as AuthError { print("Confirm sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}func confirmSignIn() -> AnyCancellable { Amplify.Publisher.create { try await Amplify.Auth.confirmSignIn(challengeResponse: "<confirmation code received via SMS>") }.sink { if case let .failure(authError) = $0 { print("Confirm sign in failed \(authError)") } } receiveValue: { signInResult in print("Confirm sign in succeeded. Next step: \(signInResult.nextStep)") }}多要素認証が有効な場合
メールまたは SMS MFA が有効になっている場合、Cognito はユーザーに代わってメッセージを送信します。メールメッセージと SMS メッセージは、ユーザーがそれぞれメールアドレスと電話番号の属性を持っている必要があります。メール MFA または SMS MFA を使用する場合は、これらの属性をユーザープールで必須に設定することをお勧めします。これらの属性が必須の場合、ユーザーはサインアッププロセスを完了する前にこれらの情報を提供する必要があります。
MFA を必須に設定し、複数の認証要素を有効にした場合、Cognito は新しいユーザーに使用する MFA 要素を選択するよう促します。SMS を選択するには電話番号が必要で、メール MFA を選択するにはメールアドレスが必要です。
利用可能なメッセージベースの MFA に必要な属性が定義されていないユーザーがいる場合、Cognito は TOTP のセットアップを促します。
バックエンド認証リソースで MFA を有効にする方法の詳細については、多要素認証のドキュメントを参照してください。
func signUp(username: String, password: String, email: String, phonenumber: String) async { let userAttributes = [AuthUserAttribute(.email, value: email), AuthUserAttribute(.phoneNumber, value: phonenumber)] let options = AuthSignUpRequest.Options(userAttributes: userAttributes)
do { let signUpResult = try await Amplify.Auth.signUp( username: username, password: password, options: options )
if case let .confirmUser(deliveryDetails, _, userId) = signUpResult.nextStep { print("Delivery details \(String(describing: deliveryDetails)) for userId: \(String(describing: userId)))") } else { print("SignUp Complete") } } catch let error as AuthError { print("An error occurred while registering a user \(error)") } catch { print("Unexpected error: \(error)") }}func signUp(username: String, password: String, email: String, phonenumber: String) -> AnyCancellable { let userAttributes = [ AuthUserAttribute(.email, value: email), AuthUserAttribute(.phoneNumber, value: phonenumber) ] let options = AuthSignUpRequest.Options(userAttributes: userAttributes) Amplify.Publisher.create { try await Amplify.Auth.signUp( username: username, password: password, options: options ) }.sink { if case let .failure(authError) = $0 { print("An error occurred while registering a user \(authError)") } } receiveValue: { signUpResult in if case let .confirmUser(deliveryDetails, _, userId) = signUpResult.nextStep { print("Delivery details \(String(describing: deliveryDetails)) for userId: \(String(describing: userId)))") } else { print("SignUp Complete") } } return sink}サインインの確認
サインイン後、次のいずれかのタイプの nextStep がサインイン結果として返されます。ユーザーのレスポンスを収集し、confirmSignIn API に渡してサインインフローを完了してください。
| 次のステップ | 説明 |
|---|---|
confirmSignInWithTOTPCode | サインインはユーザーからの TOTP コードで確認する必要があります。confirmSignIn でプロセスを完了してください。 |
confirmSignInWithSMSMFACode | サインインはユーザーからの SMS コードで確認する必要があります。confirmSignIn でプロセスを完了してください。 |
confirmSignInWithOTP | サインインはユーザーからのコード(SMS またはメールで送信)で確認する必要があります。confirmSignIn でプロセスを完了してください。 |
confirmSignInWithPassword | ユーザーは新しいパスワードを設定する必要があります。confirmSignIn でプロセスを完了してください。 |
continueSignInWithFirstFactorSelection | ユーザーは第一要素認証の優先モードを選択する必要があります。confirmSignIn でプロセスを完了してください。 |
continueSignInWithMFASelection | ユーザーはサインイン前に MFA 確認のモードを選択する必要があります。confirmSignIn でプロセスを完了してください。 |
continueSignInWithMFASetupSelection | ユーザーはセットアップする MFA 確認のモードを選択する必要があります。confirmSignIn に MFAType.email.challengeResponse または MFAType.totp.challengeResponse を渡してプロセスを完了してください。 |
continueSignInWithTOTPSetup | TOTP セットアッププロセスを続行する必要があります。confirmSignIn でプロセスを完了してください。 |
continueSignInWithEmailMFASetup | EMAIL セットアッププロセスを続行する必要があります。有効なメールアドレスを confirmSignIn に渡してプロセスを完了してください。 |
func confirmSignIn() async { do { let signInResult = try await Amplify.Auth.confirmSignIn(challengeResponse: "<confirmation code received via SMS>") print("Confirm sign in succeeded. Next step: \(signInResult.nextStep)") } catch let error as AuthError { print("Confirm sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}func confirmSignIn() -> AnyCancellable { Amplify.Publisher.create { try await Amplify.Auth.confirmSignIn(challengeResponse: "<confirmation code received via SMS>") }.sink { if case let .failure(authError) = $0 { print("Confirm sign in failed \(authError)") } } receiveValue: { signInResult in print("Confirm sign in succeeded. Next step: \(signInResult.nextStep)") }}外部 ID プロバイダーでサインイン
Google などの外部 ID プロバイダーを使用してサインインするには、signInWithWebUI 関数を使用します。
Info.plist の更新
Web UI でのサインインには、Amplify プラグインがウェブビュー内にサインイン UI を表示する必要があります。サインインプロセスが完了すると、アプリにリダイレクトします。
アプリの Info.plist でこれを有効にする必要があります。Info.plist を右クリックして、「Open As > Source Code」を選択してください。URL スキームに以下のエントリを追加してください:
<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>myapp</string> </array> </dict> </array>
<!-- ... --> </dict>Xcode 13 を使用して新しい SwiftUI アプリを作成すると、Info.plist などの設定ファイルが不要になりました。このファイルがない場合は、プロジェクトターゲットをクリックし、「Info」、「Url Types」の下の「+」をクリックして新しい URL タイプを追加してください。URL Schemes に myapp を追加してください。CFBundleURLSchemes のエントリを含む Info.plist ファイルが表示されます。
ソーシャル Web UI サインインの起動
使用しているプロバイダーを指定して以下の API を呼び出してください(以下は Facebook を使用した例):
func socialSignInWithWebUI() async { do { let signInResult = try await Amplify.Auth.signInWithWebUI(for: .facebook, presentationAnchor: self.view.window!) if signInResult.isSignedIn { print("Sign in succeeded") } } catch let error as AuthError { print("Sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}func socialSignInWithWebUI() -> AnyCancellable { Amplify.Publisher.create { try await Amplify.Auth.signInWithWebUI(for: .facebook, presentationAnchor: self.view.window!) }.sink { if case let .failure(authError) = $0 { print("Sign in failed \(authError)") } } receiveValue: { signInResult in if signInResult.isSignedIn { print("Sign in succeeded") } }}パスワードレス方式でサインイン
アプリケーションのユーザーはパスワードレス方式でサインインすることもできます。さまざまなパスワードレス認証フローのセットアップ方法を含む詳細については、パスワードレスのコンセプトページを参照してください。
SMS OTP
SMS OTP を使用したパスワードレス認証フローを開始するには、signIn API を呼び出す際に preferredFirstFactor として smsOTP を渡します。
// sign in with `smsOTP` as preferred factorfunc signIn(username: String) async { do { let pluginOptions = AWSAuthSignInOptions( authFlowType: .userAuth(preferredFirstFactor: .smsOTP)) let signInResult = try await Amplify.Auth.signIn( username: username, options: .init(pluginOptions: pluginOptions)) print("Sign in succeeded. Next step: \(signInResult.nextStep)") } catch let error as AuthError { print("Sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}
// confirm sign in with the code receivedfunc confirmSignIn() async { do { let signInResult = try await Amplify.Auth.confirmSignIn(challengeResponse: "<confirmation code received via SMS>") print("Confirm sign in succeeded. Next step: \(signInResult.nextStep)") } catch let error as AuthError { print("Confirm sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}// sign in with `smsOTP` as preferred factorfunc signIn(username: String) -> AnyCancellable { Amplify.Publisher.create { let pluginOptions = AWSAuthSignInOptions( authFlowType: .userAuth(preferredFirstFactor: .smsOTP)) try await Amplify.Auth.signIn( username: username, options: .init(pluginOptions: pluginOptions)) }.sink { if case let .failure(authError) = $0 { print("Sign in failed \(authError)") } } receiveValue: { signInResult in print("Sign in succeeded. Next step: \(signInResult.nextStep)") }}
// confirm sign in with the code receivedfunc confirmSignIn() -> AnyCancellable { Amplify.Publisher.create { try await Amplify.Auth.confirmSignIn(challengeResponse: "<confirmation code received via SMS>") }.sink { if case let .failure(authError) = $0 { print("Confirm sign in failed \(authError)") } } receiveValue: { signInResult in print("Confirm sign in succeeded. Next step: \(signInResult.nextStep)") }}Email OTP
Email OTP を使用したパスワードレス認証フローを開始するには、signIn API を呼び出す際に preferredFirstFactor として emailOTP を渡します。
// sign in with `emailOTP` as preferred factorfunc signIn(username: String) async { do { let pluginOptions = AWSAuthSignInOptions( authFlowType: .userAuth(preferredFirstFactor: .emailOTP)) let signInResult = try await Amplify.Auth.signIn( username: username, options: .init(pluginOptions: pluginOptions)) print("Sign in succeeded. Next step: \(signInResult.nextStep)") } catch let error as AuthError { print("Sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}
// confirm sign in with the code receivedfunc confirmSignIn() async { do { let signInResult = try await Amplify.Auth.confirmSignIn(challengeResponse: "<confirmation code received via SMS>") print("Confirm sign in succeeded. Next step: \(signInResult.nextStep)") } catch let error as AuthError { print("Confirm sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}// sign in with `emailOTP` as preferred factorfunc signIn(username: String) -> AnyCancellable { Amplify.Publisher.create { let pluginOptions = AWSAuthSignInOptions( authFlowType: .userAuth(preferredFirstFactor: .emailOTP)) try await Amplify.Auth.signIn( username: username, options: .init(pluginOptions: pluginOptions)) }.sink { if case let .failure(authError) = $0 { print("Sign in failed \(authError)") } } receiveValue: { signInResult in print("Sign in succeeded. Next step: \(signInResult.nextStep)") }}
// confirm sign in with the code receivedfunc confirmSignIn() -> AnyCancellable { Amplify.Publisher.create { try await Amplify.Auth.confirmSignIn(challengeResponse: "<confirmation code received via SMS>") }.sink { if case let .failure(authError) = $0 { print("Confirm sign in failed \(authError)") } } receiveValue: { signInResult in print("Confirm sign in succeeded. Next step: \(signInResult.nextStep)") }}WebAuthn パスキー
WebAuthn 認証情報を使用したパスワードレス認証フローを開始するには、webAuthn を preferredFirstFactor として渡します。
// sign in with `webAuthn` as preferred factorfunc signIn(username: String) async { do { let authFactorType : AuthFactorType if #available(iOS 17.4, *) { authFactorType = .webAuthn } else { // Fallback on earlier versions authFactorType = .passwordSRP }
let signInResult = try await Amplify.Auth.signIn( username: username, options: .init(pluginOptions: AWSAuthSignInOptions( authFlowType: .userAuth( preferredFirstFactor: authFactorType)))) print("Sign in succeeded. Next step: \(signInResult.nextStep)") } catch let error as AuthError { print("Sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}// sign in with `webAuthn` as preferred factorfunc signIn(username: String) async { Amplify.Publisher.create { let authFactorType : AuthFactorType if #available(iOS 17.4, *) { authFactorType = .webAuthn } else { // Fallback on earlier versions authFactorType = .passwordSRP }
try await Amplify.Auth.signIn( username: username, options: .init(pluginOptions: AWSAuthSignInOptions( authFlowType: .userAuth( preferredFirstFactor: authFactorType)))) }.sink { if case let .failure(authError) = $0 { print("Sign in failed \(authError)") } } receiveValue: { signInResult in print("Sign in succeeded. Next step: \(signInResult.nextStep)") }}パスワード
従来のパスワードベースの認証フローを開始するには、preferredFirstFactor として password または passwordSRP を渡します。
// sign in with `password` as preferred factorfunc signIn(username: String) async { do { let pluginOptions = AWSAuthSignInOptions( authFlowType: .userAuth(preferredFirstFactor: .password)) let signInResult = try await Amplify.Auth.signIn( username: username, options: .init(pluginOptions: pluginOptions)) print("Sign in succeeded. Next step: \(signInResult.nextStep)") } catch let error as AuthError { print("Sign in failed \(error)") } catch { print("Unexpected error: \(error)") }}// sign in with `password` as preferred factorfunc signIn(username: String) async { Amplify.Publisher.create { let pluginOptions = AWSAuthSignInOptions( authFlowType: .userAuth(preferredFirstFactor: .password)) try await Amplify.Auth.signIn( username: username, options: .init(pluginOptions: pluginOptions)) }.sink { if case let .failure(authError) = $0 { print("Sign in failed \(authError)") } } receiveValue: { signInResult in print("Sign in succeeded. Next step: \(signInResult.nextStep)") }}第一要素の選択
preferredFirstFactor パラメーターを省略して、特定のユーザーに利用可能な第一要素を検出します。これは、ユーザーがサインイン方法を選択できるようにするのに役立ちます。
その後、confirmSignIn API を使用してチャレンジを選択し、関連する認証フローを開始できます。
// Step 1: Initiate UserAuth Sign-Inlet pluginOptions = AWSAuthSignInOptions(authFlowType: .userAuth)let signInResult = try await Amplify.Auth.signIn( username: "user@example.com", options: .init(pluginOptions: pluginOptions))
switch signInResult.nextStep {case .continueSignInWithFirstFactorSelection(let availableFactors): print("Available factors to select: \(availableFactors)") // Prompt the user to select a first factordefault: break}
// Step 2: Select Authentication Factorlet confirmSignInResult = try await Amplify.Auth.confirmSignIn( challengeResponse: AuthFactorType.emailOTP.challengeResponse)
switch confirmSignInResult.nextStep {case .confirmSignInWithOTP(let deliveryDetails): print("Delivery details: \(deliveryDetails)") // Prompt the user to enter email OTP code receiveddefault: break}
// Step 3: Complete Sign-In with OTP Codelet finalSignInResult = try await Amplify.Auth.confirmSignIn( challengeResponse: "<code>")
if case .done = finalSignInResult.nextStep { print("Login successful")}func signInWithUserAuth(username: String, getOTP: @escaping () async -> String) -> AnyCancellable { Amplify.Publisher.create { // Step 1: Initiate UserAuth Sign-In let pluginOptions = AWSAuthSignInOptions(authFlowType: .userAuth) let signInResult = try await Amplify.Auth.signIn( username: username, options: .init(pluginOptions: pluginOptions) ) // Step 2: Handle factor selection if case .continueSignInWithFirstFactorSelection(let availableFactors) = signInResult.nextStep { print("Available factors to select: \(availableFactors)") // For this example, we select emailOTP. You could prompt the user here. let confirmSignInResult = try await Amplify.Auth.confirmSignIn( challengeResponse: AuthFactorType.emailOTP.challengeResponse ) // Step 3: Handle OTP delivery if case .confirmSignInWithOTP(let deliveryDetails) = confirmSignInResult.nextStep { print("Delivery details: \(deliveryDetails)") // Prompt user for OTP code (async closure) let code = await getOTP() // Step 4: Complete sign-in with OTP code let finalSignInResult = try await Amplify.Auth.confirmSignIn( challengeResponse: code ) return finalSignInResult } else { // Handle other next steps if needed return confirmSignInResult } } else { // Handle other next steps or immediate sign-in return signInResult } } .sink( receiveCompletion: { completion in if case let .failure(authError) = completion { print("Sign in failed: \(authError)") } }, receiveValue: { result in if result.isSignedIn || (result.nextStep == .done) { print("Sign in succeeded") } else { print("Next step: \(result.nextStep)") } } )}