Skip to main content

Email and SMS one-time-code authentication

Ory Network allows users to authenticate through a one-time code sent via email and SMS. This is useful for use-cases where users need to be onboarded through a minimal authentication process.

The one-time code method consists of a two-step process. The first step the user is required to enter their email address or phone number. In the second step they are prompted to enter the one-time code sent to their email address or phone number.

Below are examples of the one-time code authentication method in action:

https://ory.yourapp.com/

WebAuthn prompt

Enable email one-time-code (OTP)

  1. To enable email one-time-code, enable the one-time code strategy for passwordless:
config.yml
selfservice:
methods:
code:
passwordless_enabled: true
  1. If you are using a custom identity schema and not a preset, check the custom identity schema section.
  2. Open the login UI and test it out!
  3. You need a good email delivery provider to ensure that one-time codes are delivered reliably. We recommend setting up your own SMTP provider to ensure that you have full control over the email delivery process.

Enable SMS one-time-code (OTP)

note

Before enabling SMS one-time-code, please be aware that SMS OTP (One-Time Password) is considered insecure due to several vulnerabilities:

  1. SIM Swapping: Attackers can hijack your phone number by convincing your mobile carrier to transfer your number to a new SIM card.
  2. SMS Interception: SMS messages can be intercepted by attackers using various techniques, such as exploiting weaknesses in the SS7 protocol.
  3. Phishing: Users can be tricked into revealing their OTPs through phishing attacks.

Due to these risks, it is recommended to use more secure methods like Passkeys.

  1. To enable sms one-time-code, enable the one-time code strategy for passwordless:
config.yml
selfservice:
methods:
code:
passwordless_enabled: true
  1. Select an identity schema that has a phone number. In our case we will use the sms preset:
    1. Go to User managementIdentity schema in the Ory Console.
    2. Click the "active schema" drop down.
    3. Select the sms preset.
  2. For this example we will create a mock SMS provider. You can find more information on how to configure SMS providers in SMS delivery configuration:
    1. Set up a fake webhook endpoint using a service like webhook.site.
    2. Copy the "unique URL" of the webhook (for example https://webhook.site/859c1c...).
    3. Use the Ory CLI to set up the SMS channel:
      ory patch identity-config --project ${project_id} \
      --add '/courier/channels=[{"id":"sms","request_config":{"method":"PUT","body":"base64://ZnVuY3Rpb24oY3R4KSB7DQpjdHg6IGN0eCwNCn0=","url":"https://webhook.site/#!/view/859c1c2c-c4d5-4058-aec4-53f37929c5c1"}}]'
  3. Open the sign up page and sign up for an account.
  4. After the UI shows you that a code has been sent, check out the webhook target which will now show in response to the SMS being sent.
  5. If you are using a custom identity schema and not a preset, check the custom identity schema section.

Template customization

Customize the login and registration email templates to match your brand. You can find more information on how to do this in Emails and SMS.

Custom identity schema

All Ory Identity Schema presets are one-time code ready.

If you want to use a custom identity schema, you must define which field of the schema is the primary identifier for the one-time code strategy.

identity.schema.json
{
$schema: "http://json-schema.org/draft-07/schema#",
type: "object",
properties: {
traits: {
type: "object",
properties: {
email: {
type: "string",
format: "email",
title: "Your email",
minLength: 3,
"ory.sh/kratos": {
credentials: {
code: {
identifier: true,
via: "email",
},
// ...
},
},
},
// ...
phone_number: {
type: "string",
format: "tel",
title: "Your phone number",
minLength: 3,
"ory.sh/kratos": {
credentials: {
code: {
identifier: true,
via: "sms",
},
// ...
},
},
},
},
},
},
}