Implementing a phone number based login/signup

In today’s world, a user interacts with various apps/websites which require them to login or sign up via using their email address. There are a high chances of a person forgetting the username and the associated password to login or just completely giving up the sign up process as it asks a lot of information. Furthermore, from the app developer point of view, they will need to perform extra steps to verify the user’s email address.

One can implement a social login mechanism like github, facebook, google etc. However, users sometimes want to limit the data that gets shared with the app developers.

This leads to another solution of using phone number as a way to login to the service. It is easy to remember the phone number and we can implement a mechanism to verify that the user is in possession of this number via text messages. This article explain a simple idea of how to implement phone number based login / signup mechanism.

How it works?

We can separate the sign up process into two parts.

  1. Login Flow : In this phase, user submits the phone number to app backend and receives a token.
  2. Verify Flow : In this phase, user submits the received token in the previous phase and sends to backend. On validation, user is logged in and a session cookie is issued.

Login Flow

Figure 1: Login Flow

In order to authenticate the user account, user submits the phone number to the App Backend (an example end point can be /login). On submission, user is shown a screen where a token can be submitted. App backend validates the input parameter and enrichies/ hydrates the request with extra information like (IP address, geo information, device information etc). All this information can be used to generate a fingerprint of a user request which can be used for later security measures.

This enriched and validated request is submitted to user service which generates a token and associate with these request. Token generation is an important process here.

Token Generation

The aim of the token is to make sure we can

  • expire the token so that same token cannot be used multiple times.
  • Invalidate a token so that if a user enters the phone number multiple times then we can invalidate the previously generated token issue a new one.

We can use a sql or a no-sql datastore for this scenario. For this example, we can take use memcache as a key value datastore. We can use the inputted phone number as the key and a randomly generated 6 digit token as the value which expires in 5 minutes.

{“Key” : “+1206-123-1234”, “Value”:”123456”}

Send SMS

User service then calls a telephony API to send this token to the user’s phone number. There are various companies which provides this service (ex: Twilio, Plivo etc).

 

Verify Flow

Figure 2: Verify Phone Number Flow

On reception of the token from login flow step, users enters the token on the form. This form consists of a hidden phone number field which is submitted to an endpoint (for ex: /verify_phone) with the the token. Once again the app backend hydrates the request and validates the input parameters. The user service does a look up with the phone number as the key from the memcache data store. A session cookie is issued If the token exists and matches with the input token. This session cookie is sent as response header to the client which can persist it for later requests.

Sign up vs Login

On successful token match, user service should do a look up in the user database to see if there is an already existing account with the same phone number, if that phone number is present then the user should be logged into that account.

In case, there is not account present, then the user account should be created first and then the user should be logged into newly created account.

Few notes about security and data store selection

While implementing this approach, we should be careful about abuse scenarios. The /login endpoint can be attacked by a script which keeps on sending a request with same phone numbers. This can be handled by implementing a check of number of attempts made before sending a text out with the token in login flow.

Another issue is to consider what happens if a user changes the phone number. This involves implementing a similar mechanism of verifying the new phone number and updating the user account if that is successful.

Also, we need to consider the backend data store for this approach. In our example, we considered memcache as a key value data store which if goes down can bring this mechanism down. We can use Redis instead, as it is a persistent key value store which provides key expiration mechanism. If we want to handle key expiration logic ourselves using another mechanism (like cron) then mysql / mongodb can also be used as a datastore.

Conclusion

In this article, we talked about a simple approach towards implementing a phone number based authentication mechanism. This definitely removes the mental load on the user to remember the email and passwords across various services. Various popular companies (Uber, WhatsApp, Lyft, Telegram etc) are utilizing this approach to drive the signup and login growth metric which is a strong validation for this approach. Finally, as with any approach towards building a software functionality, one should consider the pros and cons of this approach along with the security and data store issues that we talked about.