Skip to content

messagebirdguides/verify-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Two Factor Authentication (2FA)

⏱ 15 min build time

Why build two factor authentication?

Enterprises are increasingly challenged to keep sensitive information from falling into the wrong hands. This means that we can no longer trust old online authentication systems that rely solely on usernames and passwords, especially as security breaches grow in frequency, severity and sophistication.

With the MessageBird Verify API, you can implement two factor authentication (2FA) solutions to provide an additional layer of account security by verifying the user's password with a second authentication token and in turn, secure customer data, block fraudulent accounts, and safeguard key transactions in a matter of minutes. The most common use case involves the application of one-time passwords (OTP) generated by hardware tokens or authenticator apps or directly sent to the user's mobile phone via SMS text messaging.

In this MessageBird Developer Guide, we'll introduce the MessageBird Verify API and show you how to build a runnable application in Node.js. The application is a prototype for a two factor authentication system deployed by our fictitious online banking application called BirdBank.

We'll walk you through the following steps:

  • Asking for the phone number
  • Sending a verification code
  • Verifying the code

Pro-tip: Follow this tutorial to build the whole application from scratch or, if you want to see it in action right away, you can download, clone or fork the sample application from the MessageBird Developer Guides GitHub repository.

Getting started

We'll use Node.js, the Express framework and the Handlebars templating engine as well as the MessageBird SDK to build our sample application.

Before we get started, let's make sure Node's package manager - npm - is installed. If not, you can easily download it here for free.

Project Setup

Dependencies

First, let's create a new directory to store the sample application. Now within this new directory, we'll create a file called package.json with the following content:

{
  "name": "node-messagebird-verify-example",
  "main": "index.js",
  "dependencies": {
    "body-parser": "^1.18.3",
    "dotenv": "^5.0.1",
    "express": "^4.16.3",
    "express-handlebars": "^3.0.0",
    "messagebird": "^2.1.4"
  }
}

This file provides a name for your sample application, declares the main, which we'll create next, and lists the dependencies you'll need along with their versions. Apart from Express, Handlebars, and the MessageBird SDK, we're adding a small helper library called body-parser to help simplify your code.

Next, we need to instruct npm to install all the required modules in your project. Let's open a console pointed to the directory that contains the file you just created and type the following command:

npm install

Create your API Key πŸ”‘

To enable the MessageBird SDK, we need to provide an access key for the API. MessageBird provides keys in live and test modes. To get this application running, we will need to create and use a live API access key. Read more about the difference between test and live API keys [here] (https://support.messagebird.com/hc/en-us/articles/360000670709-What-is-the-difference-between-a-live-key-and-a-test-key-).

Let's create your live API access key. First, go to the MessageBird Dashboard; if you have already created an API key it will be shown right there. If you do not see any key on the dashboard or if you're unsure whether this key is in live mode, go to the Developers section and open the API access (REST) tab. Here, you can create new API keys and manage your existing ones.

If you are having any issues creating your API key, please reach out to our Customer Support team at support@messagebird.com.

Pro-tip: Hardcoding your credentials is a risky practice that should never be used in production applications. A better method, also recommended by the Twelve-Factor App Definition, is to use environment variables.

We've added dotenv to the sample application, so you can supply your API key in a file named .env. You can copy the provided file env.example to .env and add your API key like this:

MESSAGEBIRD_API_KEY=YOUR-API-KEY

Main file

You now have your API key, so let's get started with the main file. First, we create an index.js file in the same directory as your package.json. This file starts off by including the dependencies:

var express = require('express');
var exphbs  = require('express-handlebars');
var bodyParser = require('body-parser');

Then, we initialize dotenv to load the API key from the .env file:

require('dotenv').config();

Next, append the following line to your index.js to include and set up the SDK:

var messagebird = require('messagebird')(process.env.MESSAGEBIRD_API_KEY);

Now, let's initialize and configure the framework and enable Handlebars and the body parser:

var app = express();
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
app.use(bodyParser.urlencoded({ extended : true }));

Views

We use Handlebars to separate the logic of our code from the HTML pages. To do this, we create a directory named views. Inside views we create another directory named layouts and a file called main.handlebars inside with the following content:

<!doctype html>
<html>
    <head>
        <title>MessageBird Verify Example</title>
    </head>
    <body>
        <h1>MessageBird Verify Example</h1>

        {{{body}}}
    </body>
</html>

This is the main layout which acts as a container for all pages of our application. We'll create the views for each page next.

Asking for the phone number

The first step in verifying a user's phone number is asking them to provide their phone number. Let's do exactly this by creating an HTML form and storing it as step1.handlebars inside the views directory:

{{#if error}}
    <p>{{error}}</p>
{{/if}}
<p>Please enter your phone number (in international format, starting with +) to receive a verification code:</p>
<form method="post" action="/step2">
    <input type="tel" name="number" />
    <input type="submit" value="Send code" />
</form>

The form is simple, having just one input field and one submit button. Providing tel as the type attribute of our input field allows some browsers, especially on mobile devices, to optimize for telephone number input, for example by displaying a numberpad-style keyboard. The section starting with {{#if error} is needed to display errors. We'll come back to this in a minute.

Now, it's time to add a route to your index.js to display the page:

app.get('/', function(req, res) {
    res.render('step1');
});

Sending a verification code

Once we've collected the number, we can send a verification message to the user's mobile device. MessageBird's Verify API takes care of generating a random token, so you don't have to do this yourself. Codes are numeric and six digits by default. If you want to customize the length of the code or configure other options, you can refer to the Verify API documentation.

The form we created in the last step submits the phone number via HTTP POST to /step2, so let's define this route in our index.js:

app.post('/step2', function(req, res) {
    var number = req.body.number;    
    messagebird.verify.create(number, {
        originator : 'Code',
        template : 'Your verification code is %token.'
    }, function (err, response) {
        if (err) {
            console.log(err);
            res.render('step1', {
                error : err.errors[0].description
            });
        } else {
            console.log(response);
            res.render('step2', {
                id : response.id
            });
        }
    })    
});

Before we move on, let's quickly dive into what happens here:

First, the number is taken from the request. Then, we're calling messagebird.verify.create() with the number as the first parameter. The second parameter is used to provide additional options:

  • With originator we can specify the sender ID of the text message with the code. The value should either be a valid telephone number (in international format, including country code) or an alphanumeric string with at most 11 characters. If we omitted this, it would default to the string Code. Please note that alphanumeric sender IDs do not work in a variety of countries including the United States so if you're expecting to send to these countries you must set an originator.
  • Using template we can phrase the wording of the message. The template contains the placeholder %token, which is replaced with the generated token on MessageBird's end. If we omitted this, the message would simply contain the token and nothing else.

Like most JavaScript functions, the MessageBird API call is asynchronous and transfers control to a callback function once finished. In the SDK's case, this callback function takes two parameters, err and response.

If err is set, it means that an error has occurred. A typical error could be that the user has entered an invalid phone number. For our application, we simply re-render the page from our first step and pass the description of the error into the template - remember the {{#if error} section from the first step? In production applications, you'd most likely not expose the raw API error. Instead, you could consider different possible problems and return an appropriate message in your own words. You might also want to prevent some errors from occurring by doing some input validation on the phone number yourself. We've also added a console.log(err) statement so you can explore the complete error object in your console and learn more about how it works.

In case the request was successful, we'll render a new page. Our API response contains an ID, which we'll need for the next step, so we'll just add it to the form. Since the ID is meaningless without your API access key there are no security implications of doing so, however, in practice, you'd be more likely to store this ID in a session object on the server. Just as before, we're logging the whole response to the console for debugging purposes. We still need to build the new page, so create a file called step2.handlebars in your views directory:

{{#if error}}
    <p>{{error}}</p>
{{/if}}
<p>We have sent you a verification code!</p>
<p>Please enter the code here:</p>
<form method="post" action="/step3">
    <input type="hidden" name="id" value="{{id}}" />
    <input type="text" name="token" />
    <input type="submit" value="Check code" />
</form>

The form is very similar to the first step. Note that we include a hidden field with our verification ID and, once again, have a conditional error section.

Verifying the code

The user will check their phone and enter the code into our form. What we need to do next is send the user's input along with the ID of the verification request to MessageBird's API and see whether the verification was successful or not. Let's declare this third step as a new route in our index.js:

app.post('/step3', function(req, res) {
    var id = req.body.id;
    var token = req.body.token;
    messagebird.verify.verify(id, token, function(err, response) {
        if (err) {
            console.log(err);
            res.render('step2', {
                error: err.errors[0].description,
                id : id
            });
        } else {
            console.log(response);
            res.render('step3');
        }
    })    
});

This code looks very similar to the one in the second step. First, we're reading the input and then make a call to MessageBird's API. This time, it's the messagebird.verify.verify() method, which accepts id and token as its parameters. Inside the callback, error and success cases are handled.

In case of an error, such as an invalid or expired token, we're showing that error on our page from the second step.

In the success case, we simply show a new page. Create this page in your views directory and call it step3.handlebars:

<p>You have successfully verified your phone number.</p>

Testing

Let's write one more line of code in your index.js to run the Express application:

app.listen(8080);

Now, take a quick look at the directory structure you created. It should look something like this:

node_modules
views
- layouts
- - main.handlebars
- step1.handlebars
- step2.handlebars
- step3.handlebars
index.js
package-lock.json
package.json

If you're all set, save your index.js and run the application from the command line:

node index.js

Point your browser to http://localhost:8080/ and try to verify your own phone number.

Nice work!

You now have a running integration of MessageBird's Verify API!

You can now leverage the flow, code snippets and UI examples from this tutorial to build your own two factor authentication system. Don't forget to download the code from the MessageBird Developer Guides GitHub repository.

Next steps

Want to build something similar but not quite sure how to get started? Please feel free to let us know at support@messagebird.com, we'd love to help!