Sign-in
Amplify provides a client library that enables you to interact with backend resources such as Amplify Auth.
Using the 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") } }}
The signIn
API response will include a nextStep
property, which can be used to determine if further action is required. It may return the following next steps:
confirmSignInWithNewPassword
- The user was created with a temporary password and must set a new one. Complete the process withconfirmSignIn
.confirmSignInWithCustomChallenge
- The sign-in must be confirmed with a custom challenge response. Complete the process withconfirmSignIn
.confirmSignInWithTOTPCode
- The sign-in must be confirmed with a TOTP code from the user. Complete the process withconfirmSignIn
.continueSignInWithTOTPSetup
- The TOTP setup process must be continued. Complete the process withconfirmSignIn
.confirmSignInWithSMSMFACode
- The sign-in must be confirmed with a SMS code from the user. Complete the process withconfirmSignIn
.continueSignInWithMFASelection
- The user must select their mode of MFA verification before signing in. Complete the process withconfirmSignIn
.resetPassword
- The user must reset their password viaresetPassword
.confirmSignUp
- The user hasn't completed the sign-up flow fully and must be confirmed viaconfirmSignUp
.done
- The sign in process has been completed.
For more information on handling the TOTP and MFA steps that may be returned, see multi-factor authentication.
Confirm sign-in
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)") }}
With multi-factor auth enabled
When multi-factor authentication (MFA) is required with SMS in your backend auth resource, you will need to pass the phone number during sign-up API call. If you are using the email
or username
as the primary sign-in mechanism, you will need to pass the phone_number
attribute as a user attribute. This will change depending on if you enable SMS, TOTP, or both. Visit the multi-factor authentication documentation to learn more about enabling MFA on your backend auth resource.
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}
You will then confirm sign-up, sign in, and receive a nextStep
in the sign-in result of type confirmSignInWithSMSMFACode
. A confirmation code will also be texted to the phone number provided above. Pass the code you received to the confirmSignIn
API:
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)") }}
Sign in with an external identity provider
To sign in using an external identity provider such as Google, use the signInWithRedirect
function.
Update Info.plist
Sign-in with web UI requires the Amplify plugin to show up the sign-in UI inside a webview. After the sign-in process is complete it will redirect back to your app.
You have to enable this in your app's Info.plist
. Right click Info.plist and then choose Open As > Source Code. Add the following entry in the URL scheme:
<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>
When creating a new SwiftUI app using Xcode 13 no longer require configuration files such as the Info.plist. If you are missing this file, click on the project target, under Info, Url Types, and click '+' to add a new URL Type. Add myapp
to the URL Schemes. You should see the Info.plist file now with the entry for CFBundleURLSchemes.
Launch Social Web UI Sign In
Invoke the following API with the provider you're using (shown with Facebook below):
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") } }}