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:
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:
Start the Email Passwordless Guide.
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.
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:
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:
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:
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:
- Both identity provider connections are set to enable
Automatic Linking
- 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:
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 totrue
- 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 totrue
(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.