SMS Token Authentication

Android latest version Android-O(Oreo) is changing the Android functionality by taking things to all new level. One of the highlights released in this new version(Oreo) is the hassle-free SMS Token authentication feature.

So how does this SMS authentication features works in previous versions of Android, Let’s look at it:

The current implementation of SMS authentication with different applications is imperfect. When an application needs to verify the phone number, it follows a two-step procedure:

  1. Either you have to manually check your SMS messages to find a code it has sent.
  2. Asking for total access to the SMS messages to find it itself.

Now, this is where the new SMS authentication feature comes into the picture. The new API will come into the picture at this point of the frame. It will let the Application find the code without getting access to everything. So BYE-BYE READ_SMS permission or any other permission needed otherwise.

Let’s understand more about this new API feature because this gonna change how an application authenticates the user currently.

What is an SMS Token & how does it work?

An SMS token or one-time password is a security mechanism used to authenticate or verify user identity. The user enters their phone number and a limited lifespan SMS-token is generated specifically for that user. The user then receives this token on their phone as an SMS.

When this feature is requested by an application, Android System will be alerted to an expected verification code following which Android System would start searching for any incoming SMS for any 11 characters long token. When this token is detected it is sent directly to the Application instead of routing it to the inbox. When this token is received by the application it would fire the component associated with the validation(PendingIntent) associated with the token. Another point to note here is that this application-specific token(11 characters long) does not expire until consumed by the application.

Win-Win case for the Developers !!

  • It would improve user experience to the great extent.
  • The application will have an option of authenticating phone numbers without asking for USER PERMISSION.
  • These SMS Verification code won’t clutter the inbox, thus bringing a smile to the end-User Customer.

Let’s Understand how to implement this feature in our Application:

Step 1: In your App layer build.gradle file, make these necessary changes:

android {
    compileSdkVersion 27
    buildToolsVersion "your custom version number"
    defaultConfig {
        minSdkVersion 27
        targetSdkVersion 27
        .......
        ......
    }

Step 2: Create your layout_create_token.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal|center_vertical"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/following_is_your_sms_token"
        android:textColor="@android:color/black" />

    <TextView
        android:id="@+id/tv_token"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/tv_token_top_margin"
        android:textAppearance="?android:textAppearanceMedium"
        android:textColor="@android:color/holo_red_dark" />

</LinearLayout>

Step 3: Create your CreateToken.java

In this Activity, Token is generated(smsManager.createAppSpecificSmsToken) and the PendingIntent is declared which would be fire another activity once the android system detects the SMS-Authentication token in the SMS.

public class CreateToken extends AppCompatActivity {
    public static final int REQUEST_CODE = 1001;
    public static final int FLAG = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_create_token);
        TextView textView = (TextView) findViewById(R.id.tv_token);
        SmsManager smsManager = SmsManager.getDefault();
        String appSmsToken = smsManager.createAppSpecificSmsToken
                             (createSmsTokenPendingIntent());
        textView.setText(appSmsToken);
    }

    private PendingIntent createSmsTokenPendingIntent() {
        return PendingIntent.getActivity(this, REQUEST_CODE,
                new Intent(this, SmsTokenResultVerificationActivity.class), FLAG);
    }
}

Step 4: Create the Activity layout file which wud be fired when the SMS with the intended token is received.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal|center_vertical"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/token_result_activity"
        android:textAppearance="?android:textAppearanceLarge"
        android:textColor="@android:color/holo_red_dark" />

</LinearLayout>

Step 5: Create SmsTokenResultVerificationActivity.java

This Activity does nothing except, letting the user know that the pending intent was fired and this activity has been opened upon successful retrieval of the SMS token.

public class SmsTokenResultVerificationActivity extends Activity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_sms_token_result);
    }
}

So, the question may arise in a few of the brilliant mind reading this article that how would this be implemented in client-server architecture?

For the production Applications, the SMS token generated by the android system along with the user phone number should be sent to the back-end server via an API call. The server will then receive this request and send the same token back as a text message to the user phone. The application will then receive this token and fire up the component registered in the pending Intent( In our case the SmsTokenResultVerificationActivity ). This component can then let the server know that the phone number has been verified and then proceed further with the registration/login process.

You can also replicate the above process via Emulator in following simple Steps :

Step 1: Create a Device in the Emulator with the desired configuration.

Step 2: Open your Emulator and install the Application

Step 3: Click the last button on the right-side navigation bar to open the extended control dialog and then select the phone control button.

Step 4: Generate the token through the App and type the 11 characters long token text in the message window provided.

Step 5: Tap on SendMessage

Step 6: Bingo Token Result Activity is opened in the Emulator.

Click on right corner button for more options(Highlighted with green color)
Type the SMS token and tap on the send message button
Bingo !! Verified!!

P.S: Don’t forget to add both the activities in your manifest file. You can find the complete source code here.

For any modification/suggestion feel free to reach out to me in the contact me section or you can comment below 🙂