Add SMS flows
There are a few ways to integrate phone numbers into an Amplify project's sign-in and verification process.
- As a username*: Users login with a username and password where their phone number acts as the username.
- As a verification method: Users login by any means, but must verify their account with an OTP (one time password) sent to their phone.
- MFA (Multi-Factor Authentication): Users must verify every login with an OTP sent to their phone.
*Note: This is different from using a phone number alias, which is currently unsupported by the Amplify CLI.
These methods may be combined with each other or used independently but they all require the same prerequisites for sending SMS messages via Amazon SNS, the notification service used by Amplify.
Prerequisites
Sandbox Mode
Upon enabling any of the above settings in Amplify, the CLI may prompt you with the following message:
You have enabled SMS based auth workflow. Verify your SNS account mode in the SNS console: https://console.aws.amazon.com/sns/v3/home#/mobile/text-messagingIf your account is in "Sandbox" mode, you can only send SMS messages to verified recipient phone numbers.
Follow the link to visit your SNS account. If your account is in "Sandbox" mode, you'll need to verify a phone number before you're able to send SMS messages.
Set up an Origination Entity
If you see the following banner at the top of your SNS homepage, you'll need to perform some additional steps before adding a phone number. If not, you can skip to Verify a Phone Number.
Clicking Manage origination entities will bring you to Pinpoint, where you can register an originating entity. Depending on which country you'll be sending SMS messages from, you may choose to register either a Sender ID or an Origination number.
You can find the complete list of supported options for your country here.
Sender ID
If your country supports using sender IDs, follow the instructions here to request one and enable it in your account.
Origination number
If your country does not support sender IDs, you must purchase an origination number.
In Pinpoint, scroll to Number settings
and click on Request phone number. This will bring you to a page where you can obtain a Toll-free number for sending SMS messages. Choose the country from which you'll be sending SMS messages, then follow the prompts for requesting a new number.
After successfully requesting a toll-free number, you can return to SNS to verify your phone number.
Verify a Phone Number
Return to SNS, and scroll to the Sandbox destination phone numbers
section. Click Add phone number and follow the instructions to verify your phone number.
You are now ready to setup auth for OTP.
Setup
Run amplify add auth
to create a new Cognito Auth resource, and follow the prompts below depending on how you want to integrate phone numbers into your flow.
As a username
By default, this will leave email verification enabled. If you would also like to use phone numbers for verifying users' accounts, follow the steps for As a verification method and choose Phone Number
for the sign-in method when prompted.
$ amplify add auth
? Do you want to use the default authentication and security configuration? # Default configurationWarning: you will not be able to edit these selections. ? How do you want users to be able to sign in?# Phone Number? Do you want to configure advanced settings?# No, I am done.
Some next steps:"amplify push" will build all your local backend resources and provision it in the cloud"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
As a verification method
Perform the following steps to disable email-based verification and enable SMS-based verification.
$ amplify add auth ? Do you want to use the default authentication and security configuration?# Manual configuration
... Answer as appropriate
? Email based user registration/forgot password:# Disabled (Uses SMS/TOTP as an alternative)? Please specify an SMS verification message:# Your verification code is {####}
... Answer as appropriate
Some next steps:"amplify push" will build all your local backend resources and provision it in the cloud"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
SMS MFA
Turning MFA "ON" will make it required for all users, while "Optional" will make it available to enable on a per-user basis.
$ amplify add auth ? Do you want to use the default authentication and security configuration?# Manual configuration
... Answer as appropriate
? Multifactor authentication (MFA) user login options:# ON (Required for all logins, can not be enabled later)? For user login, select the MFA types:# SMS Text Message? Please specify an SMS authentication message:# Your authentication code is {####}
... Answer as appropriate
Some next steps:"amplify push" will build all your local backend resources and provision it in the cloud"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
Run amplify update auth
and follow the prompts as guided below.
As a username
The type of username used for signing in cannot be changed after creating a user pool. If needed, first run amplify remove auth
to delete the existing user pool, then follow the New Project flow on this page for enabling phone-number sign-in.
As a verification method
Perform the following steps to disable email-based verification and enable SMS-based verification.
Note: After making this change,
Default configuration
was chosen when runningamplify add auth
. If so, it must be included withuserAttributes
in the sign up options.
$ amplify update auth
? What do you want to do?# Walkthrough all the auth configurations
... Answer as appropriate
? Email based user registration/forgot password:# Disabled (Uses SMS/TOTP as an alternative)? Please specify an SMS verification message:# Your verification code is {####}
... Answer as appropriate
Some next steps:"amplify push" will build all your local backend resources and provision it in the cloud"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
SMS MFA
As mentioned above, MFA cannot be unconditionally enabled for all users after creating a user pool. The following steps show how to enable MFA as "Optional" for users. In this mode, MFA must be enabled on a user-by-user basis, either through an Admin SDK (e.g. via a Lambda trigger as part of the sign-up process), or manually in the Cognito console.
If you'd like to make MFA required for users, you must first delete your auth resource by running amplify remove auth
, then follow the New Project flow on this page.
$ amplify update auth
? What do you want to do?# Walkthrough all the auth configurations
... Answer as appropriate
? Multifactor authentication (MFA) user login options:# OPTIONAL (Individual users can use MFA)? For user login, select the MFA types:# SMS Text Message? Please specify an SMS authentication message:# Your authentication code is {####}
... Answer as appropriate
Some next steps:"amplify push" will build all your local backend resources and provision it in the cloud"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
Sign Up
Sign up users normally with the chosen Username
type and password. Certain attributes may be required in the userAttributes
map depending on the options chosen above:
"email"
is required if:- One of the following are true:
- Email verification is enabled (default)
- Email was marked as a required attribute (default)
- and users sign up with a chosen username or phone number
- One of the following are true:
"phone_number"
is required if:- One of the following are true:
- MFA is ON, or manually enabled for the user
- Phone number verification is enabled
- Phone number was marked as a required attribute
- and users sign up with a chosen username or email
- One of the following are true:
AuthSignUpOptions options = AuthSignUpOptions.builder() .userAttribute(AuthUserAttributeKey.email(), "my@email.com") .userAttribute(AuthUserAttributeKey.phoneNumber(), "+18885551234") .build();Amplify.Auth.signUp("username", "Password123", options, result -> Log.i("AuthQuickStart", "Result: " + result.toString()), error -> Log.e("AuthQuickStart", "Sign up failed", error));
val options = AuthSignUpOptions.builder() .userAttribute(AuthUserAttributeKey.email(), "my@email.com") .userAttribute(AuthUserAttributeKey.phoneNumber(), "+18885551234") .build()Amplify.Auth.signUp("username", "Password123", options, { Log.i("AuthQuickStart", "Sign up succeeded: $it") }, { Log.e ("AuthQuickStart", "Sign up failed", it) })
val options = AuthSignUpOptions.builder() .userAttribute(AuthUserAttributeKey.email(), "my@email.com") .userAttribute(AuthUserAttributeKey.phoneNumber(), "+18885551234") .build()try { val result = Amplify.Auth.signUp("username", "Password123", options) Log.i("AuthQuickStart", "Result: $result")} catch (error: AuthException) { Log.e("AuthQuickStart", "Sign up failed", error)}
RxAmplify.Auth.signUp( "username", "Password123", AuthSignUpOptions.builder() .userAttribute(AuthUserAttributeKey.email(), "my@email.com") .userAttribute(AuthUserAttributeKey.phoneNumber(), "+18885551234") .build()) .subscribe( result -> Log.i("AuthQuickStart", "Result: " + result.toString()), error -> Log.e("AuthQuickStart", "Sign up failed", error) );
Verification of user accounts is done via the confirmSignUp
method with the OTP sent to their phone or email.
Amplify.Auth.confirmSignUp( "username", "the code you received", result -> Log.i("AuthQuickstart", result.isSignUpComplete() ? "Confirm signUp succeeded" : "Confirm sign up not complete"), error -> Log.e("AuthQuickstart", error.toString()));
Amplify.Auth.confirmSignUp( "username", "the code you received", { result -> if (result.isSignUpComplete) { Log.i("AuthQuickstart", "Confirm signUp succeeded") } else { Log.i("AuthQuickstart","Confirm sign up not complete") } }, { Log.e("AuthQuickstart", "Failed to confirm sign up", it) })
try { val code = "code you received" val result = Amplify.Auth.confirmSignUp("username", code) if (result.isSignUpComplete) { Log.i("AuthQuickstart", "Signup confirmed") } else { Log.i("AuthQuickstart", "Signup confirmation not yet complete") }} catch (error: AuthException) { Log.e("AuthQuickstart", "Failed to confirm signup", error)}
RxAmplify.Auth.confirmSignUp("username", "the code you received") .subscribe( result -> Log.i("AuthQuickstart", result.isSignUpComplete() ? "Confirm signUp succeeded" : "Confirm sign up not complete"), error -> Log.e("AuthQuickstart", error.toString()) );
You will know the sign up flow is complete if you see the following in your console window:
Confirm signUp succeeded
Sign In
Sign in users normally with the chosen Username
type and password.
Amplify.Auth.signIn( "username", "password", result -> { if (result.getNextStep().getSignInStep() == AuthSignInStep.CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE && result.getNextStep().getCodeDeliveryDetails() != null) { String destination = result.getNextStep().getCodeDeliveryDetails().getDestination(); Log.d("SignIn", "SMS code sent to "+ destination); Log.d("SignIn", "Additional Info" + result.getNextStep().getAdditionalInfo());
// Prompt the user to enter the SMSMFA code they received // Then invoke `confirmSignIn` api with the code } }, error -> Log.e("AuthQuickstart", error.toString()));
Amplify.Auth.signIn("username", "password", { result -> if (result.nextStep.signInStep == AuthSignInStep.CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE) { val destination = result.nextStep.codeDeliveryDetails?.destination Log.d("SignIn", "SMS code sent to $destination") Log.d("SignIn", "Additional Info $result.nextStep.additionalInfo")
// Prompt the user to enter the SMSMFA code they received // Then invoke `confirmSignIn` api with the code } }, { Log.e("AuthQuickstart", "Failed to sign in", it) })
try { val result = Amplify.Auth.signIn("username", "password") if (result.nextStep.signInStep == AuthSignInStep.CONTINUE_SIGN_IN_WITH_TOTP_SETUP) { val destination = result.nextStep.codeDeliveryDetails?.destination Log.d("SignIn", "SMS code sent to $destination") Log.d("SignIn", "Additional Info $result.nextStep.additionalInfo")
// Prompt the user to enter the SMSMFA code they received // Then invoke `confirmSignIn` api with the code }} catch (error: AuthException) { Log.e("AuthQuickstart", "Sign in failed", error)}
RxAmplify.Auth.signIn("username", "password") .subscribe( result -> { if (result.getNextStep().getSignInStep() == AuthSignInStep.CONTINUE_SIGN_IN_WITH_TOTP_SETUP && result.getNextStep().getCodeDeliveryDetails() != null) { String destination = result.getNextStep().getCodeDeliveryDetails().getDestination(); Log.d("SignIn", "SMS code sent to " + destination); Log.d("SignIn", "Additional Info " + result.getNextStep().getAdditionalInfo());
// Prompt the user to enter the SMSMFA code they received // Then invoke `confirmSignIn` api with the code } }, error -> Log.e("AuthQuickstart", error.toString()) );
If MFA is ON or enabled for the user, you must call confirmSignIn
with the OTP sent to their phone.
Amplify.Auth.confirmSignIn( "Confirmation code received via SMS", result -> Log.i("AuthQuickstart", result.toString()), error -> Log.e("AuthQuickstart", error.toString()));
Amplify.Auth.confirmSignIn("Confirmation code received via SMS", { Log.i("AuthQuickstart", "Confirmed signin: $it") }, { Log.e("AuthQuickstart", "Failed to confirm signin", it) })
try { val result = Amplify.Auth.confirmSignIn("Confirmation code received via SMS") Log.i("AuthQuickstart", "Confirmed signin: $result")} catch (error: AuthException) { Log.e("AuthQuickstart", "Failed to confirm signin", error)}
RxAmplify.Auth.confirmSignIn("Confirmation code received via SMS") .subscribe( result -> Log.i("AuthQuickstart", result.toString()), error -> Log.e("AuthQuickstart", error.toString()) );