Adding AWS Cognito Sign in and Sign up to Android App

Adding user Sign-in of AWS Cognito to Android app is relatively easy, so this post would be short and easy to follow. Before adding authentication to the project, we should add some prerequisites to our Android project. Basically, there are three prerequisites for each Android app which wants to connect to communicate with AWS. These are:

  1. Adding AWS Android SDK and other dependencies to the project
  2. Set Internet and network access permission to the project
  3. Adding AWS Credential to the project if we want to allow users to authenticate themselves from Google+, Facebook, etc. First, we will use Cognito, so we should add the credentials from our Cognito Pool.

Adding AWS Android SDK

For adding AWS Android SDK to the project, there are several ways, but I use the traditional one which is adding it to the dependencies of build.gradle. Each AWS services has its own dependency which should be added to the project. List of AWS dependencies can be found here.

For adding Sign-in to the application the following dependency should be added to gradle:

dependencies {
  implementation 'com.amazonaws:aws-android-sdk-core:2.7.4'
  implementation 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.7.0'
}

Add permission to the project

Generally, for accessing services of your mobile such as Bluetooth, WiFi, etc. the permissions should be added to the manifest file of the project. Because we want to authenticate the user, we need the Internet and Network Access in our App, so we add them to the manifest file which are:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

We are done configuring the project but should add Cognito Userpool configuration later. So now is time for some coding and UI. For doing that, we need to have two empty activity and one class which are:

  • Login Activity
  • Signup Activity
  • Cognito Class

Add Cognito Class to the project

After adding Cognito class to the project, add the following code to that.

import android.content.Context; 
import android.util.Log; 
import android.widget.Toast; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoDevice; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUser; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserAttributes; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserCodeDeliveryDetails; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserPool; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserSession; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.AuthenticationContinuation; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.AuthenticationDetails; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ChallengeContinuation; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.MultiFactorAuthenticationContinuation; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.AuthenticationHandler; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.GenericHandler; 
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.SignUpHandler; 
import com.amazonaws.regions.Regions; 
import static  android.content.ContentValues.TAG;
public class Cognito {
    // ############################################################# Information about Cognito Pool
    private String poolID = "Place_Your_UserPoolID";
    private String clientID = "Place_Your_ClientID";
    private String clientSecret = "Place_Your_ClientSecret";
    private Regions awsRegion = Regions.DEFAULT_REGION;         // Place your Region
    // ############################################################# End of Information about Cognito Pool
    private CognitoUserPool userPool;
    private CognitoUserAttributes userAttributes;       // Used for adding attributes to the user
    private Context appContext;
    private String userPassword;                        // Used for Login
    public Cognito(Context context){
        appContext = context;
        userPool = new CognitoUserPool(context, this.poolID, this.clientID, this.clientSecret, this.awsRegion);
        userAttributes = new CognitoUserAttributes();
    }
    public void signUpInBackground(String userId, String password){
        userPool.signUpInBackground(userId, password, this.userAttributes, null, signUpCallback);
        //userPool.signUp(userId, password, this.userAttributes, null, signUpCallback);
    }
    SignUpHandler signUpCallback = new SignUpHandler() {
        @Override
        public void onSuccess(CognitoUser cognitoUser, boolean userConfirmed, CognitoUserCodeDeliveryDetails cognitoUserCodeDeliveryDetails) {
            // Sign-up was successful
            Log.d(TAG, "Sign-up success");
            Toast.makeText(appContext,"Sign-up success", Toast.LENGTH_LONG).show();
            // Check if this user (cognitoUser) needs to be confirmed
            if(!userConfirmed) {
                // This user must be confirmed and a confirmation code was sent to the user
                // cognitoUserCodeDeliveryDetails will indicate where the confirmation code was sent
                // Get the confirmation code from user
            }
            else {
                Toast.makeText(appContext,"Error: User Confirmed before", Toast.LENGTH_LONG).show();
                // The user has already been confirmed
            }
        }
        @Override
        public void onFailure(Exception exception) {
            Toast.makeText(appContext,"Sign-up failed", Toast.LENGTH_LONG).show();
            Log.d(TAG, "Sign-up failed: " + exception);
        }
    };
    public void confirmUser(String userId, String code){
        CognitoUser cognitoUser =  userPool.getUser(userId);
        cognitoUser.confirmSignUpInBackground(code,false, confirmationCallback);
        //cognitoUser.confirmSignUp(code,false, confirmationCallback);
    }
    // Callback handler for confirmSignUp API
    GenericHandler confirmationCallback = new GenericHandler() {

        @Override
        public void onSuccess() {
            // User was successfully confirmed
            Toast.makeText(appContext,"User Confirmed", Toast.LENGTH_LONG).show();

        }

        @Override
        public void onFailure(Exception exception) {
            // User confirmation failed. Check exception for the cause.

        }
    };
    public void addAttribute(String key, String value){
        userAttributes.addAttribute(key, value);
    }
    public void userLogin(String userId, String password){
        CognitoUser cognitoUser =  userPool.getUser(userId);
        this.userPassword = password;
        cognitoUser.getSessionInBackground(authenticationHandler);
    }
    // Callback handler for the sign-in process
    AuthenticationHandler authenticationHandler = new AuthenticationHandler() {
        @Override
        public void authenticationChallenge(ChallengeContinuation continuation) {

        }
        @Override
        public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
            Toast.makeText(appContext,"Sign in success", Toast.LENGTH_LONG).show();

        }
        @Override
        public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) {
            // The API needs user sign-in credentials to continue
            AuthenticationDetails authenticationDetails = new AuthenticationDetails(userId, userPassword, null);
            // Pass the user sign-in credentials to the continuation
            authenticationContinuation.setAuthenticationDetails(authenticationDetails);
            // Allow the sign-in to continue
            authenticationContinuation.continueTask();
        }
        @Override
        public void getMFACode(MultiFactorAuthenticationContinuation multiFactorAuthenticationContinuation) {
            // Multi-factor authentication is required; get the verification code from user
            //multiFactorAuthenticationContinuation.setMfaCode(mfaVerificationCode);
            // Allow the sign-in process to continue
            //multiFactorAuthenticationContinuation.continueTask();
        }
        @Override
        public void onFailure(Exception exception) {
            // Sign-in failed, check exception for the cause
            Toast.makeText(appContext,"Sign in Failure", Toast.LENGTH_LONG).show();
        }
    };
}

In summary, this class consists of the following features:

  • registering a new user
  • Confirming new user
  • and login

Each of these methods can be called from other activities and we will call signUpInBackground from signup activity and userLogin from Login activity.

Add Signup Activity to the project

This activity can have several inputs, actually, it depends on standard attributes that you have selected in the configuration of your Cognito User Pool. During registration, the user should fill the information and be sent to the AWS Cognito service. After registration, the user will receive either an Email or SMS which consists of confirmation code. For confirming the user, the confirmation code should be sent. The following figure represents user account confirmation.

Fig. 1: Account Confirmation 2

The UI would be something like the following picture.

Fig. 2: Signup

Add Login Activity to the project

In this activity, we will have the following components in the layout:

  • Two edit text for username and password
  • One button for login
  • One text view for signing up a new user

The login activity would be like the following figure.

Fig. 3: Signin

You can download the layout files and source codes from my Github repository and add them to your project. Leave a comment below if you want the part II.

32 Comments

Add a Comment

Your email address will not be published. Required fields are marked *