Setting up SMS passwordless authentication with Auth0 and Twilio
Tags: auth, auth0, passwordless, javascript
Published: 2020-08-03 08:54:05

Following on from my previous post [on setting up passwordless for email](https://dev.to/kleeut/setting-up-email-passwordless-authentication-with-auth0-28k3). This post will go through the process of setting up SMS authentication using Twilio as the messaging service.

# Enable passswordless authentication on an application

The first thing to do is enable passwordless authentication as an option in your Auth0 tenant.
Under Authentication menu item select the Passwordless submenu item.
Click on the SMS card to open the settings.

## Configure passwordless connection

All of the required details to fill out this settings page can be found on the [Twilio Console](https://www.twilio.com/console?) after logging in.

Copy the following values from Twilio into the Auth0 SMS passwordless settings page:

- `Account SID` from Twilio into the `Twilio SID` field
- `Auth Token` from Twilio into the `Twilio Auth Token` field
- and a Twilio number from Twilio into the `From` field in Auth0. Ensure that the `Use From` options is selected.
  > Note: If you are using a trial Twilio account you'll need to request a trial number before one is available in the dashboard.

Save the settings and close the modal.
Ensure that the SMS connection is turned on.
![Turn the SMS connection on](https://dev-to-uploads.s3.amazonaws.com/i/9xueb69c4us5a0ot354g.png)

## Add the connection to an app.

Before a connection can be used it needs to be enabled as an option for that application.

To do this navigate to the applications list under the applications menu.
Open up the configuration for the app you want to enable SMS passwordless on.
Select the connections tab and enable the `sms` connection under the passwordless heading.
![Enable SMS on the application](https://dev-to-uploads.s3.amazonaws.com/i/0p5cmht4ao3nfqjiv7rq.png)

# Selecting a connection

If there is only one connection enabled for an application then selecting a connection is a moot question. Where there is more than one connection, say providing users the option to use sms or email for passwordless authentication, then it is more important. So how do you go about getting Auth0 to render the correct lock screen?

## Within the custom login page

To make use of Universal Login with passwordless authentication the tenant needs to be configured to use a custom login page. Assuming that you are using the passwordless lock to select the passwordless method the correct connection needs to be passed into the `Auth0LockPasswordless` component as the `allowedConnections` parameter. This value needs to be an array of `"email"` or `"sms"`. e.g. `allowedConnections: ["email"]`.

The default template abstracts this away by setting the connection based on the config at the top of the script and translating it into an array when the lock class is created.

```javaScript
var connection = config.connection;

...

var lock = new Auth0LockPasswordless(config.clientID, config.auth0Domain, {

...

  allowedConnections: connection ? [connection] : null

...

}
```

Setting the connection statically for all clients is a simple matter of setting the connection variable to either `"sms"` or `"email"`. Once this is done the lock screen will render with the correct input and validation for the connection.

## Selecting a connection from the web app

I've been using the [`@auth0/auth0-spa-js`](https://www.npmjs.com/package/@auth0/auth0-spa-js) npm package to build out my front end application. This doesn't work the way I had expected it to when it comes to setting which connection to use.

Both the `Auth0ClientOptions` object which is passed to the `Auth0Client` constructor and the `PopupLoginOptions` which is passed to to the `loginWithPopup` method on the `Auth0Client` instance take a `connection` property. If this is set to either `"email"` or `"sms"` the `loginWithPopup` method will throw the following exceptions.

```
 index.js:1 Error: no email or no verification_code provided
    at new n (errors.ts:2)
    at Function.n.fromPayload (errors.ts:9)
    at utils.ts:119
```

```
Error: no phone_number or no verification_code provided
    at new n (errors.ts:2)
    at Function.n.fromPayload (errors.ts:9)
    at utils.ts:119
```

To get the value to the default login page the option I've found is to set the `allowedConnections` property on the `PopupLoginOptions` object to an array of the desired connection, i.e. `["email"]` or `["sms"]`.

This is then available in the universal login page as part of the parsed config. It can be found under `config.internalOptions.allowedConnections`. If multiple connections are passed from the client app this property will be a comma separated list within a string.

The final step is to wire this selection into the lock object. Update the connection variable declaration in the default

```javascript
var connection = config.connection || config.internalOptions.allowedConnections;
```

# Final note on security

Passwordless authentication is a single factor of authentication. With the known security issues around malicious actors porting mobile phone numbers it is important to consider your security posture when using SMS based passwordless authentication. Consider using multiple factors or anomaly detection to keep your users data secure.