In this mini two part series I am going to share some code and guidance on how to use Twilio/Authy for user SMS authentication using a MEAN stack enviorment to create a full authentication system for a mobile phone app (iOS/Android) or web app.

This blog post will explore the development of the backend server; including API, MongoDB database and authenticating users. A follow-up post will explore the creation of the IONIC app (can be adapted to web app) and will be live in a couple of days. The series will cover:

Registration, validation and storing of user credentials.

Authy authentication and SMS messaging

Log in a user using token based authentication.

Protect routes and app states based on the log in user status.

All the code will be available on my GitHub page here. This repo contains the Login App and backend server. Take note of the comments within the ReadMe file. I am using the MEAN stack, but you can use any type of enviorment as the principles remain largely the same. If you are new to the MEAN stack, or want some suggestions on software, I would recommend the following

Postman: This is a Google Chrome plugin which enables you to develop, build and test your APIs.

Before we get started, I want to acknowledge Simon@Devdactic and Jason@JasonWatmore who have already made some great tutorials on this topic and aspects are utilised in this post. Secondly, I want to make it clear that for the following tutorial, while explaining all the main concepts, should not be used in a production setting in its current form.

If you are interested in the authentication API and not the SMS two-step authentication you can disable this feature in the code. However, if you are looking to implement Twilio and Authy you can register and use the free trial accounts.

Structure of the backend

In this post we are going to use MongoDB as our data store, Express.js as as our backend server, Angular.js as our front-end within the Login app and Node.js as our backend application framework. The backend folder structure looks like this

As you can see, I have clearly separated the models, routes and controller. I use a .env to store environmental variables (good practise) and a config.js file to call in these environmental variables.

NPM Install (package.json)

The package.json contains a manifest of dependancies required to operate the backend server. For the vast majority of projects you will have this file, in which you will specific the library and version range. For this project, our looks like this

We use authy for two-step authentication, bcrypt for password encryption, twilio for sending text messages and passport for user authentication. passport-jwt and jwt-simple for token generation and authentication. Morgan and mongoose are used for the data store of data credentials.

You can now go ahead and run:

npm install

Which installs the required dependancies and packages.

Defining Configuration (config.js)

The next step is to define the configuration parameters, these are used throughout the backend to define the database URL, API keys and SMS telephone numbers. The config.js should look like the following

You will notice that I am calling process.env., a good practice is to store variable values as system environment variables, and load them from there as I am doing. You should avoid hard coding these values. Your .env to run in the terminal will be

The app.js is the entry point into the node.js backend, it defines the settings, binds controllers to routes and starts the http server to listen on the specified port.

The Database - MongoDB (db.js)

Mongoose is the MongoDB driver used to access to the database and perform CRUD operations. The db.js also contains handlers in trigger in the event of the app crashing, connection failure and server shut down. The db.js should look like

What is great about this little script, it checks to ensure that the user has provided the correct JWT token, and that it is valid and the user exists. This is achieved before the request even hits our API controller.

Users Controller (users.js)

The final aspect of the backend is the user controller, which handles the creation of the user, sms notification, authentication and obtaining user accounts. The code should look like the following

module.exports.authUser: Verify the user login credentials. If they match a user in our database a token is generated for a session and they are able to access the rest of our app.

module.exports.userCreate: Provides the ability of generating a new user, sending the two-step authentication.

module.exports.verify: This is an important function, this handles the verification of the SMS code. If it is incorrect, the code is rejected.

module.exports.getUser: This enables an authorised user to obtain their account details. You will note that I am checking the JWT token within the script, this is to provide another example of how to do it within the controller. We already perform JWT authorisation in router.js.

Pulling it all Together and Testing

It is now time to pull it all together. If you have nodeman installed, you can run that, alternately you can execute the following command in the terminal directory

node app.js

You should have an output like the below in your terminal

Then you need to start Postman in your Google Chrome browser, we are going to be running the following commands:

Note: the URL may be different if you have changed the port or have a different setup. Also, make sure you have the MongoDB demon service running.

I will discuss running each API call in the following sections. Take note of all the options I have set in Postman.

Creating an account

To create an account you need to provide a username, password and mobile telephone number. Below is an example of the input, and the output

The server returns a msg which is the object ID of the user. We return this to enable us to validate the SMS text message in the next section.

SMS Validation

After registering a text message is sent via Authy, it looks like this

The message is sent to the mobile number provided during the registration process. We use the code to validate the the number, we can do this via Postman

Pay close attention to the URL, we are using POST and embedding the object ID which was sent in the previous step. Within the body, we have defined the parameter "code" which contains the Authy code.

Upon submission we receive the server response confirming the message. If all has gone well, you have now registered and validated your account. We now use Twilio to send a message to the user

Authentication

Now that the user has registered and validated their number it is time to focus on login and authentication. It is actually a very straightforward task. See the Postman below

We provide the "username" and "password" as form values and POST to the API. In return, the API provides us with an encoded token which we need to use on all future secure requests.

Get Account Details

With the token provided upon authentication we need to assign it to the headers as shown in the Postman example below

We are then able to use a GET request to obtain the details of interest.

Be sure to take a look at the MongoDB database using Robomongo to get a feel for the structure of the data.

Next Steps

In this post we have covered the development of the backend API, registration, sending Authy and Twilio messages. The next step is to extend these features to operate with an IONIC mobile phone app or a web app.

Resources

If this is still all a little new to you, you may find these resources useful when developing with MEAN: