The AWS Amplify Authentication modules provide Authentication APIs and building blocks for developers who want to create apps with real-world production-ready user authentication. With Amplify you can incorporate username / password based authentication as well as OAuth with Facebook, Google or Amazon.
We also provide a pre-built “Hosted UI” that provides a full OAuth + username / password flow. See here for more on Hosted UI.
Introduction to Amazon Cognito
The Amplify Framework uses Amazon Cognito as the main authentication provider. Amazon Cognito User is a robust user directory service that handles user registration, authentication, account recovery & other operations.
Amplify interfaces with Cognito to store user data, including federation with other OpenID providers like Facebook & Google.
The Amplify CLI automates the access control policies for these AWS resources as well as provides fine grained access controls via GraphQL for protecting data in your APIs.
Most modern applications require multiple authentication options, i.e. Facebook login + Username / password login. Amazon Cognito makes this process easy by allowing you to use a single user registry to authenticate users across multiple authentication types.
In this post, you'll learn how to add authentication to your application using Amazon Cognito and username/password login.
Setting Up the Project
If you don't already have a project you'd like to use for this tutorial, the first step is to create a new project in Android Studio. You can do that by going to File > New > New Project
. When prompted, choose Java
for the language, Empty Activity
for the activity type, and the default target version.
Now that you have a project set up, the next step is to initialize Amplify by running amplify init
in the root directory of your project.
Typically this is in the same directory as where your root build.gradle file is.
If you don't already have the Amplify CLI installed you can install it by running:
npm i -g @aws-amplify/cli
# OR
yarn global add @aws-amplify/cli
One of two things will happen when you run this command. If you have some AWS user profiles on your computer it will ask if you want to use a profile. (If you have a profile with administrative and programmatic privileges feel free to choose that.) If you don’t have any user profiles created already, or you’re unsure if a current profile will work, then the CLI will actually walk you through how to create one, even going so far as to open the AWS console for you and pre-populating any fields. (You basically just have to click a few buttons, easy peasy.)
For a more in-depth walkthrough of creating a new user profile, check out this informative video from Nader Dabit.
Now that Amplify is properly configured you can start setting up AWS services in your app!
Setting Up Authentication
Amplify makes adding services like Cognito for authentication very simple and straight-forward. To set up authentication run the following:
amplify add auth
Once you run the command you will be asked if you want to use the default configuration to set up authentication for your app. This is the recommended auth settings for AWS. (Choose this option if you aren’t familiar with how to configure your own user pools and Cognito configuration.)
Next you need to run amplify push so that the resources can be created and configured in AWS.
After Amplify creates the remote resources for your authentication service, you need to set up Amplify in your blog. To do that you need to add the necessary dependences into your app/build.gradle file:
//For AWSMobileClient only:
implementation 'com.amazonaws:aws-android-sdk-mobile-client:2.13.+'
// Cognito UserPools for SignIn
implementation 'com.amazonaws:aws-android-sdk-auth-userpools:2.13.+'
//For the drop-in UI also:
implementation 'com.amazonaws:aws-android-sdk-auth-ui:2.13.+'
For the drop-in authentication to work properly you will need to set minSdkVersion
to 23.
Next you will need to create another activity that will act as the authentication activity that will be launched instead of the main activity when users visit your app. To do that first create a new activity in your project by going to New -> Activity -> Empty Activity
. Name the activity AuthenticationActivity
, select the Launcher Activity
check box, and click Finish
.
Add the following to your new AuthenticationActivity
:
public class AuthenticationActivity extends AppCompatActivity {
private final String TAG = AuthenticationActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_authentication);
AWSMobileClient.getInstance().initialize(getApplicationContext(), new Callback<UserStateDetails>() {
@Override
public void onResult(UserStateDetails userStateDetails) {
Log.i(TAG, userStateDetails.getUserState().toString());
switch (userStateDetails.getUserState()){
case SIGNED_IN:
Intent i = new Intent(AuthenticationActivity.this, MainActivity.class);
startActivity(i);
break;
case SIGNED_OUT:
showSignIn();
break;
default:
AWSMobileClient.getInstance().signOut();
showSignIn();
break;
}
}
@Override
public void onError(Exception e) {
Log.e(TAG, e.toString());
}
});
}
private void showSignIn() {
try {
AWSMobileClient.getInstance().showSignIn(this,
SignInUIOptions.builder().nextActivity(MainActivity.class).build());
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
}
Now make sure that the AuthenticationActivity
is your launcher activity. Open AndroidManifest.xml
, and ensure that the <intent-filter>
block is specified for the AuthenticationActivity
as follows:
<!-- ... Other Code... -->
<activity
android:name=".MainActivity"
android:label="@string/app_name">
</activity>
<activity
android:name=".AuthenticationActivity"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Lastly, make sure your app is capable of accessing the network by adding the following permissions to your AndroidManifest.xml
:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Test It Out
Build and start your app in your emulator. The sign-in UI should show up as follows:
That's all there is to it! You can now sign up users to your Android apps without having to write a line of authentication code. Pair that with other Amplify categories like APIs and Storage, and you have a robust toolset to quickly build your Android apps!
Also, you should check out AWS Device Farm for testing your app across a wide range of devices and OSs (https://dev.to/kkemple/how-to-set-up-end-to-end-tests-for-android-with-zero-code-1ka).
Lastly, you can find out more about Amplify for Android here: