FusionAuth developer image
FusionAuth developer logo
  • Back to site
  • Expert Advice
  • Blog
  • Developers
  • Downloads
  • Account
  • Contact sales
Navigate to...
  • Welcome
  • Getting Started
    • Getting Started
    • 5-minute Setup Guide
      • Overview
      • Docker
      • Fast Path
      • Sandbox
    • Setup Wizard & First Login
    • Register a User and Login
    • Self-service Registration
    • Start and Stop FusionAuth
    • Core Concepts
      • Overview
      • Users
      • Roles
      • Groups
      • Registrations
      • Applications
      • Tenants
      • Identity Providers
      • Authentication/Authorization
      • Integration Points
    • Example Apps
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • PHP
      • Python
      • Ruby
    • Tutorials
  • Installation Guide
    • Overview
    • System Requirements
    • Server Layout
    • Cloud
    • Cluster
    • Docker
    • Fast Path
    • Kubernetes
      • Overview
      • Deployment Guide
      • Minikube Setup
      • Amazon EKS Setup
      • Google GKE Setup
      • Microsoft AKS Setup
    • Kickstart™
    • Homebrew
    • Marketplaces
    • Packages
    • Database
    • FusionAuth App
    • FusionAuth Search
    • Common Configuration
  • Migration Guide
    • Overview
    • General
    • Auth0
    • Keycloak
    • Amazon Cognito
    • Firebase
    • Microsoft Azure AD B2C
    • Tutorial
  • Admin Guide
    • Overview
    • Account Portal
    • Config Management
    • Editions and Features
    • Key Rotation
    • Licensing
    • Monitoring
    • Prometheus Setup
    • Proxy Setup
    • Reference
      • Overview
      • Configuration
      • CORS
      • Data Types
      • Hosted Login Pages Cookies
      • Known Limitations
      • Password Hashes
    • Releases
    • Roadmap
    • Search And FusionAuth
    • Securing
    • Switch Search Engines
    • Technical Support
    • Troubleshooting
    • Upgrading
    • WebAuthn
  • Login Methods
    • Identity Providers
      • Overview
      • Apple
      • Epic Games
      • External JWT
        • Overview
        • Example
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
        • Overview
        • Amazon Cognito
        • Azure AD
        • Discord
        • Github
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • SAML v2
        • Overview
        • ADFS
        • Azure AD
      • SAML v2 IdP Initiated
        • Overview
        • Okta
      • Xbox
    • OIDC & OAuth 2.0
      • Overview
      • Endpoints
      • Tokens
      • OAuth Modes
    • Passwordless
      • Overview
      • Magic Links
      • WebAuthn & Passkeys
    • SAML v2 IdP
      • Overview
      • Google
      • Zendesk
  • Developer Guide
    • Overview
    • API Gateways
      • Overview
      • ngrok Cloud Edge
    • Client Libraries & SDKs
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • Node
      • OpenAPI
      • PHP
      • Python
      • React
      • Ruby
      • Typescript
    • Events & Webhooks
      • Overview
      • Writing a Webhook
      • Securing Webhooks
      • Events
        • Overview
        • Audit Log Create
        • Event Log Create
        • JWT Public Key Update
        • JWT Refresh
        • JWT Refresh Token Revoke
        • Kickstart Success
        • Group Create
        • Group Create Complete
        • Group Delete
        • Group Delete Complete
        • Group Update
        • Group Update Complete
        • Group Member Add
        • Group Member Add Complete
        • Group Member Remove
        • Group Member Remove Complete
        • Group Member Update
        • Group Member Update Complete
        • User Action
        • User Bulk Create
        • User Create
        • User Create Complete
        • User Deactivate
        • User Delete
        • User Delete Complete
        • User Email Update
        • User Email Verified
        • User IdP Link
        • User IdP Unlink
        • User Login Failed
        • User Login Id Dup. Create
        • User Login Id Dup. Update
        • User Login New Device
        • User Login Success
        • User Login Suspicious
        • User Password Breach
        • User Password Reset Send
        • User Password Reset Start
        • User Password Reset Success
        • User Password Update
        • User Reactivate
        • User Reg. Create
        • User Reg. Create Complete
        • User Reg. Delete
        • User Reg. Delete Complete
        • User Registration Update
        • User Reg. Update Complete
        • User Reg. Verified
        • User 2FA Method Add
        • User 2FA Method Remove
        • User Update
        • User Update Complete
    • Guides
      • Overview
      • Authentication Tokens
      • Exposing A Local Instance
      • JSON Web Tokens
      • Key Master
      • Localization and Internationalization
      • Multi-Factor Authentication
      • Multi-Tenant
      • Passwordless
      • Registration-based Email Verification
      • Searching With Elasticsearch
      • Securing Your APIs
      • Silent Mode
      • Single Sign-on
      • Two Factor (pre 1.26)
    • Integrations
      • Overview
      • CleanSpeak
      • Kafka
      • Twilio
    • Plugins
      • Overview
      • Writing a Plugin
      • Custom Password Hashing
    • User Control & Gating
      • Overview
      • Gate Unverified Users
      • Gate Unverified Registrations
      • User Account Lockout
  • Customization
    • Email & Templates
      • Overview
      • Configure Email
      • Email Templates
      • Email Variables
      • Message Templates
    • Lambdas
      • Overview
      • Apple Reconcile
      • Client Cred. JWT Populate
      • Epic Games Reconcile
      • External JWT Reconcile
      • Facebook Reconcile
      • Google Reconcile
      • HYPR Reconcile
      • JWT Populate
      • LDAP Connector Reconcile
      • LinkedIn Reconcile
      • Nintendo Reconcile
      • OpenID Connect Reconcile
      • SAML v2 Populate
      • SAML v2 Reconcile
      • SCIM Group Req. Converter
      • SCIM Group Resp. Convtr.
      • SCIM User Req. Converter
      • SCIM User Resp. Converter
      • Sony PSN Reconcile
      • Steam Reconcile
      • Twitch Reconcile
      • Twitter Reconcile
      • Xbox Reconcile
    • Messengers
      • Overview
      • Generic Messenger
      • Twilio Messenger
    • Themes
      • Overview
      • Examples
      • Helpers
      • Localization
      • Template Variables
  • Premium Features
    • Overview
    • Advanced Registration Forms
    • Advanced Threat Detection
    • Application Specific Themes
    • Breached Password Detection
    • Connectors
      • Overview
      • Generic Connector
      • LDAP Connector
      • FusionAuth Connector
    • Entity Management
    • SCIM
      • Overview
      • Azure AD Client
      • Okta Client
      • SCIM-SDK
    • Self Service Account Mgmt
      • Overview
      • Updating User Data & Password
      • Add Two-Factor Authenticator
      • Add Two-Factor Email
      • Add Two-Factor SMS
      • Add WebAuthn Passkey
      • Customizing
      • Troubleshooting
    • WebAuthn
  • APIs
    • Overview
    • Authentication
    • Errors
    • API Explorer
    • Actioning Users
    • API Keys
    • Applications
    • Audit Logs
    • Connectors
      • Overview
      • Generic
      • LDAP
    • Consents
    • Emails
    • Entity Management
      • Overview
      • Entities
      • Entity Types
      • Grants
    • Event Logs
    • Families
    • Forms
    • Form Fields
    • Groups
    • Identity Providers
      • Overview
      • Links
      • Apple
      • External JWT
      • Epic Games
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
      • SAML v2
      • SAML v2 IdP Initiated
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • Xbox
    • Integrations
    • IP Access Control Lists
    • JWT
    • Keys
    • Lambdas
    • Login
    • Message Templates
    • Messengers
      • Overview
      • Generic
      • Twilio
    • Multi-Factor/Two Factor
    • Passwordless
    • Reactor
    • Registrations
    • Reports
    • SCIM
      • Overview
      • SCIM User
      • SCIM Group
      • SCIM EnterpriseUser
      • SCIM Service Provider Config.
    • System
    • Tenants
    • Themes
    • Users
    • User Actions
    • User Action Reasons
    • User Comments
    • WebAuthn
    • Webhooks
  • Release Notes

    Authentication With Magic Links

    Overview

    Magic link authentication allows a user to prove their identity without a password.

    With FusionAuth, magic links authentication is by default implemented with a one use, timebound code, delivered by email. However, that is not the only option. If you need more customization, you can use the passwordless API to generate a code. Then you may deliver it by another method, such as an SMS or push notification.

    This guide will cover the FusionAuth magic links authentication implementation including standard configuration, APIs you may use to build a custom experience, and system settings.

    Here’s a video showing the default magic links process in FusionAuth:

    • Magic Links

    • When Does Using Magic Links Make Sense

    • Setting Up For Magic Links

    • Using the FusionAuth Hosted Login Pages

    • Using the API Directly

    • Two Factor Authentication

    • Customizing Magic Link Authentication

    • Security

    • Troubleshooting

    Magic Links

    This feature in FusionAuth sends a secure, one time, timebound encoded code. By default, this is sent via email. When a user visits the link, they are logged in, as if by magic. They don’t need to provide any other credentials; ownership and access to the code is considered proof of who they are.

    This is also known as "magic link" login. It does not require a password, hence the general term "passwordless".

    You are not required to use email as a transport mechanism, though it is quite common. If you are using the API, you can use text messages/SMS, push notifications, or send it via carrier pigeon. As long as the user can provide the value to FusionAuth, it will be validated and the user will be logged in.

    Prior to version 1.41.0, magic links and codes were the only form of passwordless authentication supported by FusionAuth.

    Therefore the user interface and API use the term passwordless, even though versions 1.41.0 and beyond support multiple kinds of passwordless authentication.

    When Does Using Magic Links Make Sense

    Magic link authentication eases a user’s sign-in experience. Rather than having to remember which password they used, a user gives their email address and is sent a link. When they click through, they are authenticated.

    In addition to being easier for users, a magic link login experience prevents them from reusing the same password across different sites or applications. No longer will you worry about another website’s data breach causing illicit access to your system. In addition, password brute forcing is no longer a threat since the codes are one-time use.

    Setting Up For Magic Links

    If you are planning to use magic links, you have two options. The first option you can use is the FusionAuth hosted login pages. FusionAuth’s hosted login pages are customizable via themes to make each of the web pages look like your application. The other option is using the passwordless API. Let’s look at each in turn.

    In either case, you should:

    • Configure your SMTP server settings under Tenants → Email. If you are testing this flow out locally, you may want to use mailcatcher

    • Create an application

    • Turn on "Passwordless Login" under the "Security" tab of the application configuration:

      Turn on magic links passwordless login
    • Add a user and register them with your application. Make sure you register a valid email address

    Since, by default, magic links authentication requires email delivery, ensure FusionAuth is correctly configured to send email. One way to test email delivery is by creating a user and sending them a password setup email.

    Using the FusionAuth Hosted Login Pages

    Choose the FusionAuth hosted login pages approach if you want to use the Authorization Code grant. Enabling magic links adds an option for a user to receive a one-time code. Because this is the Authorization Code grant, any library or framework that supports this OAuth grant will work.

    To use this option:

    • Go to your application configuration page in the administration UI

    • Configure the OAuth redirect URL as you would with any application where users authenticate password (more on OAuth config here). Make sure the Authorization Code grant is an enabled grant

    Now you’re done with configuration.

    To test out how your users would experience this:

    1. Go to your application login page and click the "Login with a magic link" button

      The magic links login magic link.
    2. Enter the user’s email

      The magic links email request form.
    3. Go to the user’s inbox

    4. Click on the link

    As soon as the magic link is clicked, the user has begun an Authorization Code grant. You can consume the authorization code using a library or your own code. Whatever you would normally do if someone signed in with a password, you can now do here. This means that you’ll be provided with the same refresh tokens, user data, or JWTs that would be delivered if the user had signed in with a password.

    To customize the look of the login pages, use themes. While editing the theme, you could remove the username/password form. This would force everyone to use magic links authentication.

    Since changing a theme modifies it across all applications in a tenant, this might also affect the FusionAuth admin application (if the new application is in the default tenant) and other applications in the same tenant. If you want to hide the username/password form on an application by application basis, you can use separate tenants or add logic to your theme to hide parts of the HTML based on the client_id, or you can use application specific themes. The latter are a feature requiring a paid license.

    Limitations

    There are a few limitations when using the FusionAuth hosted login pages:

    • This approach will only send the magic code via email

    • This approach also requires you to enable the Authorization Code or Implicit grant

    Using the API Directly

    While using the FusionAuth hosted login pages works for many, you may need more control or flexibility. You can use the passwordless API to authenticate a user with a one-time code. The API reference docs cover each of the API calls, but this guide will walk you through an implementation.

    There are a couple of reasons you might choose this method of integration.

    • You can customize every part of the user login experience

    • You can send the code using a different method such as a text message or Slack direct message

    When using this option, you must set up an API key with the appropriate permissions. The minimum level of privilege required is the POST permission to the /api/passwordless/start endpoint.

    Calling the API

    There are four parts to build your own magic link flow.

    1. You start the magic link login via an API call to FusionAuth

    2. Deliver the code to the user

    3. The user enters the code

    4. You complete the magic link login via an API call

    Starting the login

    You start a magic link login by calling the /api/passwordless/start endpoint.

    Start Magic Link Login API call
    
    API_KEY=...
    REQUEST_PAYLOAD='{...}'
    curl  -H "Content-type: application/json" -H "Authorization: $API_KEY" https://local.fusionauth.io/api/passwordless/start -d $REQUEST_PAYLOAD

    Here’s an example request payload:

    Start Magic Link Login Request JSON
    
    {
      "applicationId": "10000000-0000-0002-0000-000000000001",
      "loginId": "jared@piedpiper.com",
      "state": {
        "client_id": "10000000-0000-0002-0000-000000000001",
        "redirect_uri": "https://piedpiper.com/callback",
        "response_type": "code",
        "scope": "openid",
        "state": "CSRF123"
      }
    }

    The state property in the JSON is optional. If present, it is echoed back to your application at the end of the magic link login workflow. This allows anonymous users to interact with your application, then log in and have data from their anonymous session available.

    For example, if you have a shopping site, you may want to allow a user to add items to their cart before they sign in. Once they have logged in, the state parameter can be used to associate their cart id with the authenticated user. In this case, the state key might be set to a JSON object like this:

    
    { "cart_id" : 1234 }

    The call to /api/passwordless/start begins the authentication process, and returns a response with a code:

    Start Magic Link Login Response JSON
    
    {
      "code" : "CynAUMCHLxCCAWyHXOVWPQd8ZY0a6U0e3YpYkT0MNxs"
    }

    Possession of this one-time code authenticates the end user. Deliver this code to the end user using whatever method you’d like. If you want to use FusionAuth to deliver the code via email, see Sending the Code Using FusionAuth.

    Sending the Code Using FusionAuth

    This is an optional API call. If you want to send the code via the email server configured in FusionAuth, you may use the /api/passwordless/send API endpoint.

    Using this API call allows you the benefits of FusionAuth locale-aware email templates and email delivery capabilities without requiring you to use the FusionAuth login forms.

    The User Enters the Code

    Once the user possesses the code, they must provide it to your application. You must build an interface for them to do so.

    Completing the Login

    When the user provides the code to you, call the /api/passwordless/login endpoint. You can pass other information such as IP address, but only the code is required.

    Complete Magic Link Login Request JSON
    
    {
      "code" : "CynAUMCHLxCCAWyHXOVWPQd8ZY0a6U0e3YpYkT0MNxs"
    }

    If the code is valid, your application will receive user data, a JWT, and other data based on the application configuration. If you send a state property in the JSON when starting the authentication process, it will also be included in the response, under the state key.

    Complete Magic Link Response JSON
    
    {
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo",
      "state": {
        "client_id": "10000000-0000-0002-0000-000000000001",
        "redirect_uri": "https://piedpiper.com/callback",
        "response_type": "code",
        "scope": "openid",
        "state": "CSRF123"
      },
      "user": {
        "active": true,
        "birthDate": "1976-05-30",
        "connectorId": "e3306678-a53a-4964-9040-1c96f36dda72",
        "data": {
          "displayName": "Johnny Boy",
          "favoriteColors": [
            "Red",
            "Blue"
          ]
        },
        "email": "example@fusionauth.io",
        "expiry": 1571786483322,
        "firstName": "John",
        "fullName": "John Doe",
        "id": "00000000-0000-0001-0000-000000000000",
        "imageUrl": "http://65.media.tumblr.com/tumblr_l7dbl0MHbU1qz50x3o1_500.png",
        "lastLoginInstant": 1471786483322,
        "lastName": "Doe",
        "middleName": "William",
        "mobilePhone": "303-555-1234",
        "passwordChangeRequired": false,
        "passwordLastUpdateInstant": 1471786483322,
        "preferredLanguages": [
          "en",
          "fr"
        ],
        "registrations": [
          {
            "applicationId": "10000000-0000-0002-0000-000000000001",
            "data": {
              "displayName": "Johnny",
              "favoriteSports": [
                "Football",
                "Basketball"
              ]
            },
            "id": "00000000-0000-0002-0000-000000000000",
            "insertInstant": 1446064706250,
            "lastLoginInstant": 1456064601291,
            "preferredLanguages": [
              "en",
              "fr"
            ],
            "roles": [
              "user",
              "community_helper"
            ],
            "username": "johnny123",
            "usernameStatus": "ACTIVE"
          }
        ],
        "timezone": "America/Denver",
        "tenantId": "f24aca2b-ce4a-4dad-951a-c9d690e71415",
        "twoFactorEnabled": false,
        "usernameStatus": "ACTIVE",
        "username": "johnny123",
        "verified": true
      }
    }

    The user is now authenticated. Your application has user data, pre-existing state if provided, and a JWT which can be used to represent the user to other resources. If you want to send the JWT to a client as a cookie, you can now do so.

    Additional Magic Link Login Parameters

    JWTs are typically passed to other systems like an API server to enable access to protected resources (more about JWTs). If you are using magic link authentication and are not using the JWT, you can turn off its generation. Creating and signing the JWT requires server resources; turning JWT generation off will improve performance.

    To do so, set the noJWT parameter to true when you call the complete API endpoint.

    Common Failure Paths

    Every time you start a magic link login for a given user, all other codes for that user are marked invalid. Codes are also invalid after a configurable time limit.

    If a user provides a code that is invalid, if their account is locked, or if there is any other issue in the request, a status code in the 400 range will be returned. Please consult the passwordless API reference docs for more details about return status codes.

    Two Factor Authentication

    You can use FusionAuth magic link authentication in combination with two-factor authentication (also called multi-factor authentication or MFA).

    When two-factor authentication is enabled for a user, after the one-time code has been provided they are prompted to provide an additional two-factor verification code.

    Learn more about setting up two-factor authentication.

    Two Factor Authentication With the API

    Two factor authentication also works when using the API. In that case, when you complete the magic link authentication, instead of getting the user data, you’ll get a twoFactorId:

    
    {"twoFactorId":"VnNILnXs_EDG-cjwokwITRApmAxCMkojeT3CUqqLhLc"}

    Your application must then prompt the user for their two-factor code, from SMS or an application like Google Authenticator. Note that this is an entirely different code than the one-time code returned when you started the magic link login. Pass the twoFactorId and the two-factor code to the /api/two-factor/login endpoint in order to complete the two-factor authentication.

    If a user has previously completed a two-factor authentication and has decided to trust the device, you may have a twoFactorTrustId value. This can be passed to the /api/passwordless/login endpoint. If valid, this will skip the two-factor challenge.

    Customizing Magic Link Authentication

    You can configure the FusionAuth passwordless implementation to meet your application’s needs.

    Templates

    If you are using the FusionAuth provided email templates, whether you are using the standard FusionAuth user interface or the /api/passwordless/send call, you will need to customize them. Since the template references "FusionAuth", duplicate the template:

    Duplicate the magic link login email template.

    Then modify it with your branding and messaging.

    Modifying the magic link login email template.

    Configure the tenant email template settings to use your template.

    Updating the tenant to use the new magic link email template.

    When customizing, you can use any Apache FreeMarker built-ins within the template and in the subject. Make sure you modify both the HTML and text templates. Here are the default templates:

    The Default Magic Link HTML Template
    
    [#setting url_escaping_charset="UTF-8"]
    You have requested to log into FusionAuth using this email address. If you do not recognize this request please ignore this email.
    <p>
      [#-- The optional 'state' map provided on the Start Passwordless API call is exposed in the template as 'state' --]
      [#assign url = "https://local.fusionauth.io/oauth2/passwordless/${code}?tenantId=${user.tenantId}" /]
      [#list state!{} as key, value][#if key != "tenantId" && value??][#assign url = url + "&" + key?url + "=" + value?url/][/#if][/#list]
    
      <a href="${url}">${url}</a>
    </p>
    - FusionAuth Admin
    The Default Magic Link Text Template
    
    [#setting url_escaping_charset="UTF-8"]
    You have requested to log into FusionAuth using this email address. If you do not recognize this request please ignore this email.
    
    [#-- The optional 'state' map provided on the Start Passwordless API call is exposed in the template as 'state' --]
    [#assign url = "https://local.fusionauth.io/oauth2/passwordless/${code}?tenantId=${user.tenantId}" /]
    [#list state!{} as key, value][#if key != "tenantId" && value??][#assign url = url + "&" + key?url + "=" + value?url/][/#if][/#list]
    
    ${url}
    
    - FusionAuth Admin

    You can localize the template as well:

    The localization screen for your email templates.

    Here is more information about email templates.

    Customizing the Subject

    Here’s an example of how to customize the subject with FreeMarker. The subject below shows how to customize the subject with the time the link expires.

    Customizing the subject
    
    [#setting time_zone = (user.timezone)!"US/Denver"]
    [#setting time_format = "h:mm a"]
    Expires at: ${((.now?date?long + timeToLive * 1000)?number_to_time)?string}

    One Time Code Customization

    You can modify the lifetime of the code delivered to users. By default it is 180 seconds; change this in the tenant settings:

    The tenant settings to customize code lifetime and generation strategy.

    You can also change the type of the code generated. For example, you may want your code to be only alphanumeric characters.

    You may change your code length or generation strategy for security or user experience reasons. You may have requirements that specify a certain code length. If you deliver the code by text message, having a user enter a six digit alphanumeric code sent to them by SMS is a lot easier than a 64 byte string.

    You have the following options for the code generation strategy:

    • alphabetic characters

    • alphanumeric characters

    • bytes

    • digits

    Consult the tenant API documentation for the length limits, which vary based on the strategy.

    Security

    With magic link authentication, if the user’s email account is hijacked, their account on your system is compromised. However, many organizations have security policies and protections around email accounts. It is often easier to protect and regularly change one email account password than to change all of a user’s passwords. Email accounts are also more likely to have two-factor authentication enabled.

    One way to increase the security of your magic link authentications is to decrease the lifetime of the code. This will help if the email is compromised or accidentally forwarded.

    There are no limits on how many passwordless requests can be made for a user, but only the most recent code is valid. Using any of the others, even if they have not yet expired, will display an Invalid login credentials message to the user.

    If someone tries to log in with an email that is not present in the FusionAuth user database, they’ll see the same notification as they would if the email existed. No email will be sent.

    If you use the passwordless API, follow the principle of least privilege, and limit calls to which the API key has access. If you are using the API key only for magic link passwordless login, don’t give this key any other permissions.

    What About Users' Passwords

    When FusionAuth is your user datastore, adding a user means you must either provide a password or send them a link to set up their initial password.

    If you are only allowing magic link authentication for your application, don’t allow the user to specify a password and instead generate a random series of characters for the password. We recommend generating at least 32 characters in the ascii character set that are completely random to ensure the user’s account is secure.

    Troubleshooting

    Email

    If you are experiencing troubles with email deliverability, review the email troubleshooting documentation.

    Invalid Links

    In some cases, email clients will visit links in an email before the user does. In particular, this is known to happen with Outlook "safe links". If the client does this when the email contains a passwordless one time code, that code may be invalid when the user clicks on it, as it has already been "used" by the client.

    One option is to consult with your email client administrator. It may be possible to add the application’s URL to an allow list.

    In version 1.27, FusionAuth changed the link processing behavior to remedy this for some situations. Given the wide variety of email client behavior, it may still be present in other scenarios.

    If your users' passwordless codes are being expired by an email client, please file a GitHub issue.

    Feedback

    How helpful was this page?

    See a problem?

    File an issue in our docs repo

    Have a question or comment to share?

    Visit the FusionAuth community forum.

    © 2023 FusionAuth
    Subscribe for developer updates