DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Software Design and Architecture
  3. Security
  4. Better Two Factor Authentication Experiences With WebOTP

Better Two Factor Authentication Experiences With WebOTP

This article explains how the WebOTP API makes for better two-factor authentication experiences on the web.

Phil Nash user avatar by
Phil Nash
·
Dec. 12, 22 · Tutorial
Like (3)
Save
Tweet
Share
2.57K Views

Join the DZone community and get the full member experience.

Join For Free

Two-factor authentication (2FA) is a great way to improve the security of user accounts in an application. It helps protect against common issues with passwords, like users picking easily guessable passwords or reusing the same password across multiple sites. There are different ways to implement two-factor authentication, including SMS, an authenticator application, and WebAuthn.

SMS is the most widely used and won’t be going away, so it falls on us as developers to do our best to build the best SMS 2FA experience for our users. The WebOTP API is one way we can help reduce friction in the login experience and even provide some protection against phishing.

What Is the WebOTP API?

The WebOTP API is an extension of the Credential Management API. The Credential Management API started by giving us the ability to store and access credentials in a browser’s password manager, but now encompasses WebAuthn and two-factor authentication. The WebOTP API allows us to request permission from the user to read a 2FA code out of an incoming SMS message.

When you implement the WebOTP API, the second step of the login process can go from an awkward process of reading and copying a number of digits from an SMS to a single button press. A great improvement, I think you’ll agree.

An animation showing a login experience where after entering a username and password, a permissions dialog pops up asking for permission to read a 2FA code from an SMS. When approved, the code is entered into an input and the form submitted.

How Does it Work?

To implement WebOTP, you will need to do two things:

  1. Update the message you send with the WebOTP format.
  2. Add some JavaScript to the login page to request permission to read the message.

The SMS Message

To have the WebOTP API recognize a message as an incoming 2FA code, you need to add a line to the end of the message that you send. That line must include an @ symbol followed by the domain for the site that your user will be logging in to, then a space, the # symbol, and then the code itself. If your user is logging in on example.com and the code you are sending them is 123456, then the message needs to look like this:

Your code to log in to the application is 123456

@example.com #123456

The domain ties the message to the website the user should be logging onto. This helps protect against phishing; WebOTP can’t be used to request the code from an SMS if the domain the user is logging in to doesn’t match the domain in the message. Obviously, it can’t stop a user from copying a code across from a message, but it might give them pause if they come to expect this behavior.

The JavaScript

Once you have your messages set up in the right format, you need some JavaScript on your second-factor page that will trigger the WebOTP API, ask the user permission for access to the message and collect the code.

The most minimal version of this code looks like this:

 
if ('OTPCredential' in window) {
  navigator.credentials.get({
    otp: {
      transport: ['sms']
    }
  }).then((otp) => {
    submitOTP(otp.code);
  });
}


We ask the navigator.credentials object to get a one-time password (OTP) from the SMS transport. If the browser detects an incoming message with the right domain and a code in it, the user will be prompted, asking for access. If the user approves, the promise resolves with an otp object which has a code property. You can then submit that code to the form and complete the user’s login process.

A more complete version of the code that handles things like finding an input and form, canceling the request if the form is submitted, and submitting the form if the request is successful, looks like this:

 
if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    const ac = new AbortController();
    const form = input.closest('form');
    if (form) {
      form.addEventListener('submit', e => ac.abort());
    }
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
      input.value = otp.code;
      if (form) {
        form.submit();
      }
    }).catch(err => {
      console.error(err);
    });
  });
}


This will work for many sites, but copying and pasting code isn’t the best way to share code, so I came up with something a bit easier.

Declarative WebOTP With Web Components

On Safari, you can get similar behavior to the WebOTP API by adding one attribute to the <input> element for the OTP code. Setting autocomplete="one-time-code" will trigger Safari to offer the code from the SMS via autocomplete.

Inspired by this, I wanted to make WebOTP just as easy. So, I published a web component, the <web-otp-input> component, that handles the entire process. You can see all the code and how to use it on GitHub. For a quick example, you can add the component to your page as an ES module:

 
<script type="module" src="https://unpkg.com/@philnash/web-otp-input"></script>


Or install it to your project from npm:

 
npm install @philnash/web-otp-input


And import it to your application:

 
import { WebOTPInput } from "@philnash/web-otp-input";


You can then wrap the <web-otp-input> around your existing <input> within a <form>, like this:

 
<form action="/verification" method="POST">
  <div>
    <label for="otp">Enter your code:</label>
    <web-otp-input>
      <input type="text" autocomplete="one-time-code" inputmode="numeric" id="otp" name="otp" />
    </web-otp-input>
  </div>
  <button type="submit">Submit</button>
</form>


Then the WebOTP experience will happen automatically for anyone on a browser that supports it without writing any additional JavaScript.

WebOTP: A Better Experience

The WebOTP API makes two-factor authentication with SMS a better experience. For browsers that support it, entering the code that is sent as a second factor becomes a breeze for users.

There are even circumstances where it works for desktop browsers too. For a user with Chrome on the desktop and Chrome on Android and signed into their Google account on both, signing in on the desktop will cause a notification on the mobile device asking to approve sending the code to the desktop. Approving that on mobile devices transfers the code to the desktop browser. You don’t even have to write more code to handle this; all you need is the JavaScript in this article.

If you are building two-factor authentication or phone verification, consider implementing the WebOTP API as well to make that process easier for your users.

API SMS authentication Factor (programming language) security Application security

Published at DZone with permission of Phil Nash, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How To Avoid “Schema Drift”
  • Microservices Discovery With Eureka
  • Architectural Miscalculation and Hibernate Problem "Type UUID but Expression Is of Type Bytea"
  • 2023 Software Testing Trends: A Look Ahead at the Industry's Future

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: