[Deprecated] Implementing SMS passwordless authentication in Android Using Firebase, Auth0, and Twilio

Idorenyin Obong
6 min readFeb 11, 2017

--

Brethren, I finally decided to start my career as a developer evangelist this year in an attempt to follow in the footsteps of my mentors in this field like Hanson Johnson , Prosper Otemuyiwa , etc., after successfully implementing this API in my yet to be released mobile application. This took three months after enduring frustrating times in the attempt. In this first outreach, I hope to simplify this implementation for all those interested.

Passwordless authentication is a type of authentication where users do not need to login with passwords but instead they are provided with a one time password or a magic link. One popular application that uses this is Whatsapp where a user is sent a one time code in order to be authenticated.

Authentication with password is redundant in the following ways:
To a developer, it can be tedious and easily prone to mistakes;
To the user, he/she might not keep up with remembering all passwords and this causes users to use one password for almost all platforms. For a better introduction on how this works, you can read this article by Prosper Otemuyiwa on How Passwordless Authentication Works https://t.co/0kfaDiwfZo

Lets Begin…

Create a new android project: Open android studio, create a new application and keep the minimum sdk at 14. The name of my application is MyApplication.

Create a new Firebase project and add Firebase to your android project:
Just if you didn’t know, Firebase is a mobile and web application platform with tools and infrastructure designed to help developers build high-quality apps. Some of these tools include: user authentication, a no-SQL database, Cloud messaging services, etc… Visit console.firebase.google.com and create a new project. Follow the instructions thereafter to add firebase to your android project. If you have issues generating a sha1 key, use this link http://stackoverflow.com/a/33479550/6538897 .

Download Firebase services file: Go to settings in your Firebase app, select the service accounts tab, click on generate new private key. A json file will be downloaded. This file contains the secrets to our implementation. Keep it safe!

Now to the toughest part of the implementation of this API due to poor user experience of Twilio.

Create a Twilio account: Twilio is a cloud communications platform as a service company which allows software developers to programmatically make and receive phone calls, send and receive text messages using its web service APIs. We will use the Twilio API to enable us send sms to our mobile phones. Go to their website, www.twilio.com and create an account.

Because of difficulty in navigation, i will post direct links.

Get a number responsible for the messaging by following this link https://www.twilio.com/console/phone-numbers/incoming . Click on ‘request a number’. A number will be generated for you, accept the number and keep it safe.

Go to https://www.twilio.com/console/sms/settings/geo-permissions to enable Messaging Geographic Permissions for countries you wish to.

Go to https://www.twilio.com/console/phone-numbers/verified and add numbers you which to use for testing since this is a trial account so as to avoid extra charges.

Go to https://www.twilio.com/console/account/settings and scroll to API credentials, copy the details for Live credentials. i.e Account SID and Auth Token and keep safely. The Auth Token is usually hidden, click it to unveil it.

Create Auth0 account and enable the Firebase addon:
Auth0 is a service that abstracts how users authenticate to applications. You can connect any application (written in any language or on any stack) to Auth0 and define its Connection, the method used to authenticate the users of that application. In a nutshell, Auth0 makes user authentication easier.

Go to manage.auth0.com, create an account. After sign up or log in, you will be redirected to dashboard. Select clients-(https://manage.auth0.com/#/clients) and create a new client. Choose native as the client type and finish creating the project. As soon as the project is created, you will be redirected to quick start. Select android native SDK quick guide.

Scroll to set credentials; copy the client id and auth0 domain to the strings.xml file in your android project.

Select the add ons tab and enable the Firebase addon and a dialog will come up, select the settings tab and you are to fill the private key id, private key, client email. These details are found in the services json file downloaded earlier. Save and close the dialog.

Click connections on the left hand side and select passwordless (https://manage.auth0.com/#/connections/passwordless) and enable sms passwordless connection. A dialog will appear, input the Account SID, Auth token, and the phone number gotten earlier into the ‘Twilio SID’ field, ‘Twilio Auth Token’, and ‘From’ fields in the dialog. Still in the dialog, select the Apps tab and enable your app. Always make sure to save. You can use the try tab for testing and be sure you will receive a one time password provided you have abided by the laws.

Now to the implementation in android:
add the following file to your build.gradle file and sync it.

compile 'com.google.firebase:firebase-core:10.0.1'
compile 'com.google.firebase:firebase-auth:10.0.1'
compile 'com.auth0.android:lock-sms:1.10.+'

We have imported the lock-sms library, and the Firebase libraries necessary for this implementation.

We declare our LocalBroadcastManager, FirebaseAuth, and Firebase.AuthStateListener variables.

private LocalBroadcastManager broadcastManager;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;

We will then add and remove authStateListener in the onStart and onStop method respectively, initialize mAuth, mAuthListener, and the broadcastManager variables, register thebroadcastManager with a reciever, ‘authenticationReceiver’ and also called the LockSMSActivity.

@Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
@Override
public void onStop() {
super.onStop();
if (mAuthListener != null) mAuth.removeAuthStateListener(mAuthListener);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {

@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
Log.d("TAG", "onAuthStateChanged:signed_in:" + user.getUid());
} else {
Log.d("TAG", "onAuthStateChanged:signed_out");
}
}
};
broadcastManager = LocalBroadcastManager.getInstance(this);
broadcastManager.registerReceiver(authenticationReceiver, new
IntentFilter(Lock.AUTHENTICATION_ACTION));
startActivity(new Intent(MainActivity.this, LockSMSActivity.class));
}
LockSMSActivity

We now declare the LockSMSActivity and CountryCodeActivity in the manifest file

<activity
android:name=”com.auth0.lock.sms.LockSMSActivity”
android:label=”@string/app_name”
android:launchMode=”singleTask”
android:screenOrientation=”portrait”
android:theme=”@style/Lock.Theme” />
<activity
android:name="com.auth0.lock.sms.CountryCodeActivity"
android:theme="@style/Lock.Theme" />

We will then set up the broadcast receiver which will receive the user’s token from Auth0 after a successful authentication. The token received is then used to fetch a delegation token. The delegation token is used to sign the user into the Firebase database using the signInWithCustomToken.

private BroadcastReceiver authenticationReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final UserProfile profile = intent.
getParcelableExtra(Lock.AUTHENTICATION_ACTION_PROFILE_PARAMETER);
Token token= intent.
getParcelableExtra(Lock.AUTHENTICATION_ACTION_TOKEN_PARAMETER);
Lock lock = Lock.getLock(MainActivity.this);
APIClient client = lock.getAPIClient();
String apiType = "firebase";
String token_id = token.getIdToken();
Map<String, Object> parameters = ParameterBuilder.newEmptyBuilder()
.set("id_token", token_id)
.set("api_type", apiType)
.setAccessToken(token.getAccessToken())
.setClientId(getString(R.string.auth0_client_id))
.asDictionary();
client.fetchDelegationToken(parameters, new BaseCallback<Map<String, Object>>() {

@Override
public void onSuccess(Map<String, Object> payload) {
mAuth.signInWithCustomToken(payload.get("id_token").toString())
.addOnCompleteListener(MainActivity.this, new OnCompleteListener<AuthResult>() {

@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d("TAG", "signInWithCustomToken:onComplete:" + task.isSuccessful());

if (!task.isSuccessful()) {
Log.w("TAG", "signInWithCustomToken", task.getException());
} else {
/* The user is now signed in to your Firebase database, you can redirect from here.
*/
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();}
}

});

}
@Override
public void onFailure(Throwable error) {

}
});
}
};

We have to also unregister the receiver in the onDestroy method.

@Override
protected void onDestroy() {
super.onDestroy();
broadcastManager.unregisterReceiver(authenticationReceiver);
}

Create an AppController class which extends the application class and implements Lock provider. Initialize the lock variable and return the variable in the override getLock method.

public class AppController extends Application implements LockProvider {
private Lock lock;
@Override
public void onCreate() {
super.onCreate();
lock = new Lock.Builder()
.loadFromApplication(this)
.closable(true)
.build();
}
@Override
public Lock getLock() {
return lock;
}
}

Request for internet permission in the manifest file.

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

Add your client id and Auth0 domain values to the manifest file under the application tag

<meta-data
android:name="com.auth0.lock.client-id"
android:value="@string/auth0_client_id" />
<meta-data
android:name="com.auth0.lock.domain-url"
android:value="@string/auth0_domain" />

set the application name to “AppController”

<application
android:name=".AppController" >

TADA!!!!!!!!!!!!
We’ve successfully implemented this API.

If you run your application, Lock’s sign in screen should appear to begin authentication right away!

--

--