How to verify mobile numbers using Zensend’s SMS API

How to verify mobile numbers using Zensend’s SMS API

It's more and more frequent for apps to use mobile phone numbers to verify a user’s identity or to provide an extra layer of security when logging a user into an account.

You might want to verify a user’s phone number as an additional way of checking that they are human and not a bot in order to decrease spam or abusive behaviour on your website. You also might want to verify a user's phone number that they have previously provided during log in as an additional factor for authentication.

In this tutorial we will illustrate in 4 easy steps how to use Zensend's SMS API in order to verify a user's phone number. The examples are shown in PHP, but could easily be replicated in other languages and frameworks. I've chosen to use images to display the code examples if you click on the image you will be given the plaintext on Github.

Step 1: Collect a user's phone number

In this example we use the excellent JQuery International Telephone Input plugin to allow the user to specify which country they are in and type in their phone number in their local format. It is important to know what country a user is in because sending an SMS requires an international phone number and user's might not know how to specify their phone number in this format. The plugin also performs validation to make sure the user's phone number has been entered in the correct format.

The following code displays the form to collect the user's phone number:

And we use the following javascript code to setup the JQuery International Telephone Input plugin, perform the validation and submit the phone number to PHP in international format.

Step 2: Generate a random token

Next, we use the random_int(100000, 999999) in order to generate a random 6 digit token. random_int is only available on PHP >= 7 but there are polyfills for earlier PHP versions. In this blog post we use the random_compat polyfill. It is possible to use rand or mt_rand to generate the token but these are not cryptographically secure random number generators and it may be possible for an adversary to guess tokens generated by your application. If you are depending on the phone number verification for security (rather than to simply confirm the user is human) it is is very important to use random_int.

We also store the token, the msisdn to be verified and the time we created the token in the PHP session.

Step 3: Send SMS with the token

In this step we use the Zensend PHP API in order to send the token via SMS to the user.

The following code is used:

After sending the token to the user we redirect the user to a page where they can enter the token they have received:

Step 4: Verify the token

And then finally we have a form that allows the user to enter the token they have received. The HTML looks like this:

When the user submits the token we perform a number of checks:

We check that they have been sent a token:

We check that the token has not expired:

We check they have not reached the maximum number of failed attempts:

We check that the token is equal to the one they sent and if correct we add the verified phone number to the session. We use hash_equals to prevent timing attacks.

We also increment the number of attempts and if further attempts will automatically fail we inform the user they have run out of attempts:

Two-factor authentication (2FA)

That’s it. in four easy steps we’ve shown you how to add mobile phone number verification to your web application. This work can also be repurposed for doing two-factor authentication by permanently associating the user’s phone number with the user’s account After the user logs in with their password then this known phone number can be verified.

Further Work

This solution does not have any throttling to prevent someone from sending lots of tokens either to abuse another person’s mobile phone or to falsely verify by brute forcing the token. For example sending 300,000 tokens with three attempts each the attacker has roughly a 40% chance of guessing a correct six digit token. Additionally, for example Recaptcha could be used to make it harder to abuse or an attempt limit/throttling based on phone number could be introduced.

Also, this solution does not have protection against cross site request forgery attacks. This is beyond the scope of this tutorial and it assumed that this will be included by the framework a user chooses to use. For example the slim framework has inbuilt support for protection against CSRF.

All of the code in this blog is available on Github and if you have an Apache server setup with PHP you can just edit the config.inc file to include your Zensend API key and try it out!

Got questions about this blog, our products or APIs? Drop us a comment here or send us a tweet @hellozensend.

To view or add a comment, sign in

Others also viewed

Explore content categories