How-tos

Passport + Twilio: Two-factor authentication for Customer Identity Management

Share this post:

IBM is building the next generation cloud platform that provides necessary tools and services to application developers. IBM Cloud platform, built on open technology, gives developers the power they need to build without the traditional ‘do it yourself’ approach to feature development. When you build applications on IBM Cloud, you can leverage the ecosystem of tools they provide to add additional features to your application outside of your expertise.

Multi-factor Authentication

Passport is a powerful customer identity and access management (CIAM) platform that is used by companies to reduce development costs and time-to-market. A key feature of Passport is multi-factor authentication, sometimes referred to as MFA.

A specific type of multi-factor authentication is two-factor authentication which utilizes two components to verify a user’s identity. The two components being something you know, such as your login credentials and something you possess. This particular type of multi-factor authentication will be the topic for the remainder of the article.

Traditionally, two-factor authentication requires an extra application or device that would generate a 6-digit code. For example, a user might have an application on their smartphone or an RSA code generator on a key fob. The generated code is then used to verify a user’s identity after they supply their username and password.

While this system works, it is often cumbersome for users to install and configure this application on their mobile phone. A simpler alternative is to utilize a push service to send a text message to the user’s mobile phone containing the code.

When we decided to add push notifications for two-factor authentication, it became clear that the transport for sending users a push notification with a security code does not line up with our core competency. Twilio has planted themselves firmly as a leader in messaging services, which made them an ideal choice to fill this gap for Inversoft.

Both Passport and Twilio are listed in the IBM Cloud Catalog and work together seamlessly to send push notifications containing two-factor codes to enable secure user authentication.

In this example, Passport and Twilio are used to develop a simple application with push notifications to deliver the two-factor verification codes. If you’re already a Passport customer, enabling the Twilio integration can be done with a few clicks. Let’s get started!

Tools Needed

Get Started

Create a simple login page that takes a username and password. In this case, the email is used as the username. I’m using React for this example. Below is the React component that supplies the login page and the corresponding rendered output.

class Login extends Component {
  render() {
    return (
      <div className="login" >
        <form id="login">
          <label><input id="loginId" name="loginId" type="text"/></label>
          <label><input id="password" name="password" type="password"/></label>
          <input type="submit" value="Login"/>
        </form>
       </div>
    );
  }
}
export default Login;

The form above will be submitted by the user and the React component will make an AJAX request to Passport to authenticate the user. This request is made using the Login API. See documentation. Here’s the AJAX code that makes the login API call to Passport:

const xhr = new XMLHttpRequest();
xhr.onreadystatechange = (function() {
  if (xhr.readyState === XMLHttpRequest.DONE) {
    if (xhr.status === 200) {
      // Handle successful login
    } else if (xhr.status === 242) {
      // Handle 2FA Challenge
    } else if (xhr.status === 400) {
      // Input validation, missing required values
    } else if (xhr.status === 404) {
      // Invalid loginId or password
    } else {
      // Login failed for other reasons
    }
  }
});

const request = {
  loginId: 'cosmo@playtronics.com',
  password: 'too many secrets',
  applicationId: '486e7225-b59a-4eff-802d-fc9452d85226'
};

xhr.open('POST', 'http://localhost:9011/api/login', true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.send(JSON.stringify(request));

The Login API will return a variety of HTTP status codes depending on the situation. For this example, the user has enabled two-factor authentication, and therefore Passport will respond with an HTTP status code of 242 that indicates the user’s credentials were valid. However, a two-factor code will be required to complete login.

Passport + Twilio

To enable the Twilio integration in Passport, navigate to Integrations by clicking on Settings and then Integrations and click on the Twilio icon. See the example below.

To configure Twilio in Passport you’ll need:

  • API URL (the URL to connect to the Twilio Service).
  • Account SID (Twilio account SID found on your Twilio dashboard)
  • Auth Token (Twilio authorization token found on your Twilio dashboard)
  • The phone number assigned to your Twilio account or the messaging service Id if you’re using the Copilot service

Once you have entered the required values, enter your mobile phone number in the Test configuration section to validate your configuration before saving your configuration. You should receive a message on your mobile phone that says You’ve successfully configured the Twilio integration for Passport. See the example below.

For this example, I created a user in Passport with my cell phone number and two-factor authentication enabled to test this portion of my code. This ensures that I receive a push message from Passport sent via Twilio when I login. This must be done through an API or a custom registration form. I used the User API to create my user.

Below is an example screenshot of the two factor code on my phone. The trial message will not be present on your production Twilio account.

To complete the process, create a form in the React app that will accept the code that was pushed to the user’s mobile phone and send it to Passport.

Here’s the React component to accept the two-factor code:

class TwoFactor extends Component {
  render() {
    return (
      <div className="login" >
        <form id="two-factor">
          <label><input id="code" name="code" type="text"/></label>
          <input type="submit" value="Complete Login"/>
        </form>
      </div>
    );
  }
}
export default TwoFactor;

The form above will be submitted by the user and the React component will make an AJAX request to Passport to complete login by calling the Two Factor Login API. See documentation.

This API returns a HTTP status code of 200 if the request was successful and the response also includes the User object and a JWT. If the code is incorrect, the HTTP status code will be 421.

Here is the AJAX code to make the API call to Passport. Notice it is nearly identical to the Login API except it takes a code and twoFactorId instead of loginId and password.

const xhr = new XMLHttpRequest();
xhr.onreadystatechange = (function() {
  if (xhr.readyState === XMLHttpRequest.DONE) {
    if (xhr.status === 200) {
      // Handle successful login
    } else if (xhr.status === 400) {
      // Input validation, missing required values
    } else if (xhr.status === 404) {
      // Invalid or expired twoFactorId, return to login
    } else if (xhr.status === 421) {
      // Invalid two-factor code, try again
    } else {
      // Login failed for other reasons
    }
  }
});

const request = {
  code: '522909',
  twoFactorId: 'YkQY5Gsyo4RlfmDciBGRmvfj3RmatUqrbjoIZ19fmw4',
  applicationId: '486e7225-b59a-4eff-802d-fc9452d85226'
};

xhr.open('POST', 'http://localhost:9011/api/two-factor/login', true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.send(JSON.stringify(request));

That’s it, you’re done! With just a few clicks and minimal code, two-factor authentication is successfully enabled using Twilio.

The code examples in this article are simplified to make them easier to understand. These examples can be found in a working example application on Github. For full integrated examples review the example source code provided in the linked Github project.

If you’d like to learn more about Passport, visit our inversoft.com/passport and review our documentation. We would love to hear if there are any other Passport integrations you’d like to see in the future. Please let us know in the comment section below, on email or Twitter @inversoft.

More How-tos stories

Speed up your WordPress with IBM Cloud

WordPress is one of the most popular content management systems available, but the many websites and blogs that use it experience issues with speed. At IBM Cloud, there are several solutions that can help alleviate some of these issues and allow you to have a better and faster WordPress experience.

Continue reading

Container Native Monitoring Insights with Elastic on IBM Cloud

Introduction to container native monitoring In this blog post, we will discuss how Elastic easily deploys with the IBM Cloud Kubernetes Service (IKS). This provides full visibility of your containerized workloads and operational consistency with container deployments in a multi-cloud architecture. We will deploy a Kubernetes cluster in IBM Cloud and layer in the Elastic […]

Continue reading

Build, Deploy, and Scale Real-World Solutions on IBM Cloud

IBM Cloud Solution Tutorials give you step-by-step instructions to create applications running on virtual servers, Kubernetes, Cloud Foundry, and serverless architectures. The tutorials also cover topics ranging from web and mobile applications, chatbots, IoT, and machine learning and analytics.

Continue reading