A reminder of why we’re here, using these passcodes all the time.
One-Time Passcodes (OTP’s) allow websites and apps to add an additional layer of security, by requiring users to verify their identity by supplying a single-use code sent to a device that they have previously proven ownership of. This helps to confirm that the person using a service is the same person who signed up for it.
This also assures us as users, whether we’re making payments, signing in to critical services or recovering our passwords, that nobody else can take this action and pretend to be us.
Statista recorded that 33% of online accounts in the UK were protected by OTP in 2022, so it is a significant step in the user experience for site owners to support.
Best practices for One-Time Passcode Formatting
As a consumer, using an OTP is often pretty awkward. Switch from the app or web browser to your messages app, opening the message, select the code, copy it, go back to the app you were using, paste it in, submit it.
There are several best practices and technologies that can make this experience not only much more pleasant, but can also increase the rate of success for usage of OTP’s and reduce the amount of time taken to complete authentication, ultimately helping your business increase its conversion rates.
Let’s work through all of the aspects that we as developers can consider for optimizing the OTP user journey:
- The best way to format OTP SMS
- What is the best format for an OTP SMS?
- What is the best length for a One-Time Passcode?
- Multi-language support for OTP
- Considerations across devices for OTP usage
- Web Standards
- Best practices for web applications using OTP
What is the best format for an OTP SMS?
Both iOS and Android use heuristics (rules of thumb) to identify and parse OTP messages, so following those rules of thumb will maximize the chance that your messages will be correctly identified by the device when they arrive.
At a minimum it should include the word ‘code’ or ‘passcode’ in order for the phone to process it. Successful examples we have seen include:
Formatting messages carefully will support their seamless use when they arrive. The way in which OTP messages are treated varies by platform, so there are a few scenarios to consider. We’ll break those down later on, so you know what to test for when you’re building your application.
There are no hard and fast rules governing the message format, so you should experiment by sending yourself several different test OTP text messages, to confirm which perform well and which do not.
What is the best length for a One-Time Passcode?
Avoiding non-numeric characters (i.e. letters and special characters like exclamation marks) in your passcodes is critical to support devices parsing these codes properly.
We commonly see codes of between 4 and 8 characters in length. You’ll want to find the right balance between a length that (1) secures your application from brute force attack and (2) is still easy for the user to remember.
Spaces can be used in longer codes, to make them easy to recall as pairs or triplets (that’s why we have spaces in phone numbers), but this can result in the handset failing to identify them correctly as OTP messages and reduces the chance that the supporting technologies on the device will be able to use them. Again, a little experimentation here will help if you want to use longer codes.
Multi-Language Support for OTP
To cater for people using languages other than English you can use their first language when delivering passcodes via SMS. Again you should experiment with different message formats, to ensure that the devices recognize your messages as containing One-Time Passwords. Direct translations of the word ‘code’ or ‘passcode’ should also be used in the appropriate language to help with AutoFill when the user receives the message.
Whilst multilingual messaging is of course advisable, you should not veer away from using the regular (i.e. Western Arabic numeral) format for the actual passcode. So, if your message is cyrillic, don’t use cyrillic numbers, but rather their western counterparts. This supports their standard usage in your application, where you will most likely have no idea what your user’s first language is.
Considerations across devices for OTP usage
There are several scenarios to consider once the OTP message arrives, determined by (1) the type of device the user has and (2) whether it will be used in native application on that device or in a web browser. This is what you should expect to happen, if your OTP messages are interpreted successfully:
In iOS 12 Apple introduced Security Code Autofill, which allows the iPhone to detect the OTP in Messages and display it on the QuickType bar above the keyboard, as an AutoFill suggestion. The user then simply has to tap the passcode in order to use it. This applies to native apps running on the device and to web pages you provide for OTP submission in the browser.
If a security code arrives whilst a valid text input field is in focus (i.e. when the keyboard is displayed) the QuickType bar will display security codes that it can parse from Messages for up to 3 minutes.
If the system parses your security code in the Messages app, users should see the code underlined in the message bubble. They can then tap the code to copy it before going back into the relevant app and pasting it in.
To help with your testing, the format of messages that Apple devices will recognize is defined in the Password Autofill documentation on the Apple Developer site.
Google released the SMS Retriever API in 2019, which allows Android apps to be alerted when an SMS arrives on the device. This allows the app to provide a prompt for the user to accept the code and submit it automatically, providing a very smooth verification journey. SMS Messages must constructed in a strict format, including an 11-character hash of your Google Play Store app ID, for this to work. If you have a native Android app then this will be a special case on your development roadmap.
With the release of iOS 14, Apple introduced support for Domain-bound passcodes, to better match OTP messages to the site they are intended for. This involves appending the website domain and a hash, followed by the OTP code to the SMS (see the screenshot below), which allows both the user and the device to verify a match before the code is used. This helps to protect users from malicious sites pretending to be who they are not, and stealing personal information (this is what’s called ‘phishing’).
The API uses the global ‘navigator’ object in the browser to assign the OTPs to the credentials parameter. Developers can create an event listener to react to incoming SMS that the browser identifies for the site, then use the navigator.credentails.get() function to retrieve and submit the code for the user automatically. This removes the need for the user to jump between applications.
Best practices for web applications using OTP
With the considerations above in mind, several best practices can be employed when we build web forms that need to support OTP:
- Generate domain-bound passcodes to send to your users.
- Use a single field for users to complete passcodes. Multiple fields prevent the user from easily pasting in a passcode, as well as adding extra complexity for developers to autocomplete and submit forms automatically.
- Include the autocomplete=”one-time-code” attribute on your OTP input field, to encourage the browser to populate the field with parsed OTPs.
- If your OTPs are always numeric then you can use the type=“number” attribute on your input field, so that the numeric keypad appears by default when the field gains focus, to make it easy to enter code if the user has to type it. This doesn’t work as well on desktops however, as browsers will render the up and down arrows in the field. To solve this problem you can use the inputmode=“numeric” attribute to suit both use cases.
- Add an event listener to the paste event on your input field, with a fallback to the onchange event.
- Check whether the browser supports the ‘OTPCredential’ standard, and add an event listener to take advantage of the Web OTP API wherever it’s available.
SMS remains a universally accessible way to deliver One-Time Passcodes. With significant support from device and browser vendors it is a sensible choice for many site owners to add an extra layer of security to their applications.