Skip to main content

Custom Passwordless Login

This guide details how to set up a passwordless flow. The same flow can be used to configure users to log in with an email address, a phone number, or any other custom flow you might have. You can direct the user to a custom login screen, then use Authress to generate a login code, and then forward the user to that screen to log in with the code. Authress supports this via the Custom connection configuration.

The easiest way to set this up is first configure a custom connection that you own. Instead of adding a custom connection to handle a third party provider that doesn't offer a compliant OAuth2.1 or SAML connection, you can set up a custom connection to handle your additional needs explicitly.

Background: The Authress login flowโ€‹

The standard Authress login flow, starts in your web app. The user requests to login, which generates a login request using one of your configured Authress connections. The connectionId and applicationId are passed to the login SDK. This is a similar flow to what your application is already using to login with Authress, As a reminder these are the relevant SDK methods:

(Application UI) Log a user into your application
import { LoginClient } from '@authress/login';
const loginClient = new LoginClient({
// Both of these properties can be found and configured at:
// https://authress.io/app/#/manage?focus=applications
authressApiUrl: 'https://auth.yourdomain.com',
applicationId: 'YOUR_APPLICATION_ID'
});

// We'll be replacing this with the `authenticateWithOneTimeCode` as we'll see below:
// await loginClient.authenticate({ connectionId: 'SERVICE_CLIENT_ID' });
// So that will become, for OneTimeCode flows
await loginClient.authenticateWithOneTimeCode({ serviceClientId: 'SERVICE_CLIENT_ID' });

Setupโ€‹

The setup for the passwordless flow follows the Authress Custom Identity Provider connection guide. Follow this guide and once completed return to this page. The guide walks through creating new component for handling email collection and email sending. Once completed your flow should look like this:

Email passwordless setup

Start the Email Passwordless Guide.

info

In that guide where you see the use of the Verified User ID, replace that with the user's email address.

1. Enable the Custom Passwordless Login Flowโ€‹

The first step is to create a new service client. This client will be given the permissions to start and complete the flow. This prevents malicious users from abusing the passwordless flow to hijack user accounts.

Generate a new Authress Service Client. Enter a name for the client, and select the option to Enable custom Authress user token generation. This allows this client to directly communicate with the Authress login API to request user identity tokens.

Enable the legacy authorization service

Your Service Client represents your API that will send the passwordless one time code to the user's email. Enter the API's endpoint in the Authorization Url property:

Create a passwordless connection

2. Update your application codeโ€‹

After the custom service client is created with the appropriate configuration, the next step is to update your application to enable the custom login flow. Instead of calling the authenticate() method, instead call the authenticateWithOneTimeCode() passing in the required properties:

(Application UI) Authenticate using the Magic Link / One Time Code
import { LoginClient } from '@authress/login';
const loginClient = new LoginClient({
// Both of these properties can be found and configured at:
// https://authress.io/app/#/manage?focus=applications
authressApiUrl: 'https://auth.yourdomain.com',
applicationId: 'YOUR_APPLICATION_ID'
});

// This will redirect the user to the specified connection login UI,
// track their session with Authress, and then redirect back to your specified
const redirectUrl = window.location.href;
const result = await loginClient.authenticateWithOneTimeCode({ connectionId: 'SERVICE_CLIENT_ID', redirectUrl });

// Next call your passwordless service client receiver with the necessary properties.
// The name `generateUserLoginUrlAndSendEmail` is up to you, for this example we've used it for clarity.
await myCustomReceiver.generateUserLoginUrlAndSendEmail({
emailAddress: 'user@email.company.com',
authenticationRequestId: result.authenticationRequestId,
redirectUrl
})

3. Create your receiverโ€‹

At this point have the user's intent to login (the authenticationRequestId) and the user's email are available. Now it is time to send the email and wait for the user to click the link.

Create your endpoint to generate the Authress one time code assertion, and send to the user:

Get User Login URL
import { ServiceClientTokenProvider } from '@authress/sdk';

/**
* authenticationRequestId {string} - This value is returned by the Authress Login SDK when calling the authenticateWithOneTimeCode
* redirectUrl {string} - The redirectUrl is the same one passed to the Authress Login SDK. This must be the same value.
*/
function generateUserLoginUrlAndSendEmail({ authenticationRequestId, redirectUrl, emailAddress }) {
const serviceClientId = 'SERVICE_CLIENT_ID';
const accessKey = 'SERVICE_CLIENT_ACCESS_KEY';

const tokenProvider = new ServiceClientTokenProvider(accessKey);
const authressLoginUrl = await tokenProvider.generateUserLoginUrl(redirectUrl, authenticationRequestId, serviceClientId, emailAddress.toLowerCase());
await sendEmailToUserEmail(emailAddress, authressLoginUrl);
}

4. Authentication completeโ€‹

When the user clicks on the link in the email, they'll be logged into Authress, and be redirected back to the redirectUrl you specified in the previous step.

[Optional] Automatic connection linkingโ€‹

When a user logs in Authress supports automatically linking the current login connection with other login connections if:

  1. Both identity provider connections are set to enable Automatic Linking
  2. Both generate user identities contain the email_verified: true property.

To enable Automatic Linking for both connections, go to Authress > Identity Connections > Select the connection > Advanced Tab > User Identity Linking. And then select: Automatically link identities whenever possible:

Automatic User Identity Linking

Second, Authress will validate that the user identity that is returned from the provider has a trusted contact data. Not all providers return a contact email, and not all emails nor providers are trustworthy. If the provider is trusted via (1) above, and that the provider trusts the contact data from the user, usually the email address, then the user will automatically logged in with their already existing user identity.

As an example, if:

  • A user logged in Google previously
  • Google set the email_verified property to true
  • The Authress preconfigured Google connection is set to enable Automatic Linking

And then the user logs into a second connection, such as your custom passwordless or another preconfigured connection AND:

  • That connection has Automatic Linking enabled
  • The user identity return from the provider includes the email_verified property set to true (This value is automatically set by the Authress SDKs.)

Then the user will automatically be logged in with their previous user identity and the user ID assigned to the user will be the same.

If either connection is set to Explicit Linking or if either connection does not have the email_verified attribute, then users can be linked using the Linking User Identity strategy guide.