Email and phone verification
Ory allows users to verify email addresses associated with their accounts. This is important to prove that the user has access to the address they used to create their account. If verification is enabled, Ory Identities starts the verification process automatically when users sign up. Users can also verify their addresses manually.
The verification flow is supported in both browsers and API clients.
Completing account verification doesn't guarantee that the account is used by the person who performed the verification. We recommend implementing additional security mechanisms to ensure that verified accounts aren't taken over by malicious actors.
Configuration
- Ory Console
- Ory CLI
To configure account verification, go to Authentication → Email Verification in the Ory Console.
Download the Ory Identities config from your project and save it to a file:
## List all available projects
ory list projects
## Get config
ory get identity-config {project-id} --format yaml > identity-config.yamlAdd the configuration for the verification flow
config.ymlselfservice:
methods:
code: # or link
enabled: true
config:
# Defines how long the verification or the recovery code is valid for (default 1h)
lifespan: 15m
flows:
verification:
use: code # Defines which method is used, one of 'code' or 'link'.
enabled: true
# Defines how long the verification flow (the UI interaction, not the link!)
# is valid for (default 1h)
lifespan: 15mUpdate the Ory Identities configuration using the file you worked with:
ory update identity-config {project-id} --file updated_config.yaml
Identity schema
To make an address verifiable, it must be marked as such in the
identity schema. In most cases this is the email address the user
provides when registering their account. Other fields inside the traits
section are supported as well.
{
"$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"traits": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
}
},
+ "verification": {
+ "via": "email"
+ }
}
}
}
"additionalProperties": false
}
}
}
Email templates
Ory Identities comes with default email templates for verification flows.
You can quickly replace the defaults and customize the messages to match the look and feel of your solution. Read the custom email template documentation to learn more.
When users attempt to initiate verification for unregistered addresses, the system sends a message to the email address that was used in the attempt.
This prevents account enumeration attacks as explained in this blog post by Troy Hunt.
Allow login only with verified email
To allow only the users with a verified email to sign in, follow these steps:
- Ory Console
- Ory CLI
Go to Authentication → Email Verification in the Ory Console and enable Require Verified Address for Login.
Download the Ory Identities config from your project and save it to a file:
## List all available projects
ory list projects
## Get config
ory get identity-config {project-id} --format yaml > identity-config.yamlAdd the configuration for the verification flow
selfservice:
flows:
login:
+ after:
+ hooks:
+ - hook: require_verified_addressUpdate the Ory Identities configuration using the file you worked with:
ory update identity-config {project-id} --file updated_config.yaml
For more information see the hooks configuration documentation.
Choosing the right strategy
Ory supports two strategies for verifying your user's addresses.
- One-time codes
- Magic Links
When using one-time codes to verify a user's address, Ory Identities sends an email with a 6-digit code to the user. They must enter the code in a dedicated UI text field to verify their address.
The email also contains a link, that takes the user to the verification form with the code pre-filled in the appropriate form field. The only thing the user must do to verify their address is to submit the form.
When using the "magic link" method, Ory Identities sends the user an email with a verification link. If the user has access to the email associated with the account and clicks the link, Ory Identities marks that address as verified.
If the user completes the verification after the link or code expired, they must provide the email address associated with their account to get a new verification email.
Comparison
"One-time code" (code
) is the default, preferred, and recommended method by Ory.
Ory supports "magic links", but considers this method a legacy solution. Currently, the method is supported but should be considered deprecated and is set to be removed in future releases.
Consider using the code
method as it mitigates many of the drawbacks of "magic links":
- Some email virus scanners open links in emails to scan them. This invalidates the link and may prevent users from completing the flow even if they have the access to the defined address.
- Flows initialized by apps on mobile phones or smart devices don't work with links.
- Depending on the device settings, clicking a link from an email can open a different browser than the one used to initialize the flow. This can confuse your users.
When you change the strategy from link
to code
in an existing project, you might need to adjust your UI. Make sure the flow
works correctly with your UI implementation after changing the strategy.
Code examples
The user interface for account verification is a page in your solution that renders the actual form elements for the user.
In contrast to other identity systems, Ory Identities (Ory Kratos) doesn't render this HTML directly. Instead, you need to implement the HTML code in your solution, which gives you complete flexibility and customizability in your user interface flows and designs. This part of your application then directly interfaces with Ory Identities through the API.
The API responds with a JSON document describing the form elements to render and actions the form should take upon submission, cancellation, etc. The following shows examples for a few different languages and frameworks.
- Browser UI
- Golang (API Flow)
- Express.js
- React.js
- React Native
- Verification View
- Generic Form View
- Example Input Form Element
- Generic Form View
- Example Input Form Element