OTP Authentication with SMS using Twilio in Meteor

Posted on Jun 02, 2017

OTP Authentication with SMS using Twilio in Meteor

Using OTP or SMS authentication is a very useful feature to have in an app. It provides two-factor security and verification in addition to the authentication layer. Twilio provides a very useful SMS API that can be used to implement such a feature. Here I will take you through the general process to implement Twilio SMS authentication in Meteor user signup and registration.

Packages

First, you need to install one of the following packages:

Next, you should also install the okland:accounts-phone package to help enable login via phone number. Their GitHub provides easy to follow instructions on how to set it up.

Password

It is strongly recommended to create user accounts with a password, along with the phone number. It is a good security feature to have and is also required by default on Meteor Accounts package.

Verification Process

So here I will be giving an example using server-side Meteor methods. For frontend you can write your Blaze, React or AngularJS handlers accordingly.

This example will be using the HTTP package. If you wish, you can modify it to include other wrapper packages like twilio-meteor in your code.

Flow Chart of OTP Authentication with Twilio in Meteor

Step 1: Register your user and send OTP verification SMS.

createNewUser method:


'createNewUser': (password, phoneNumber) => {
  const min = 10000,
    max = 99999,
    OTP = Math.floor(Math.random() * (max - min + 1)) + min,
    dbUser = Meteor.users.findOne({ username: phoneNumber });
  
  if (dbUser) {
      // user already exists
      return throw new Meteor.Error('error',
        `User already exists for ${phoneNumber}`);
  }
  
  // user does not exist  
  const user = {
    username: phoneNumber,
    password,
    profile: { 
      OTP, 
      isMobileVerified: false, 
    },
  };
  
  // send verification code
  Meteor.call('sendSMS', OTP, phoneNumber, (error) => {
      if(error) {
        return throw new Meteor.Error('error', error);
    }
    
    // create user
    return Accounts.createUser(user);
  });
}

sendSMS method:


'sendSMS': (code, mobile) => {
  // call twilio API
  HTTP.call(
    'POST',
    'https://api.twilio.com/{yyyy-dd-mm}/Accounts/' + 
    '{TWILIO_APPKEY}' + '/SMS/Messages.json', {
      params: {
        From: '{YOUR_NUMBER}',
        To: mobile,
        Body: `Greetings! Your OTP is ${code}`,
      },
      auth: '{TWILIO_APPKEY}' + ':' + '{TWILIO_PASSWORD}'
    }, function (error) {
      if (error) {
          console.log('API request failed.');
        return throw new Meteor.Error('error', error);
      }
      console.log('SMS sent successfully.');
    };
  );
}

Step 2: Ask user for verification code and check code input by user

verifySMS method:


'verifySMS': (code, phoneNumber) => {
  const user = Meteor.users.findOne({ username: phoneNumber });
  const { OTP } = user.profile;
  
  if(!OTP || OTP !== code) {
      return throw new Meteor.Error('error', 'Invalid OTP.');
  }
  return Meteor.users.update({ username: phoneNumber }, {
    $set: { 'profile.isMobileVerified': true },
    $unset: { 'profile.OTP': 0 },
  });
}

 

Lastly, you need to use the above methods in client side. From your client-side code handling, you can make a request to the Meteor method. Then if the input code matches, approve the user. Else display appropriate error message.

Voila! This is all you need to implement OTP SMS based authentication for user signup in Meteor.