Passwordless sign-in
Users should access an application without creating or remembering passwords.
Better Auth · Function
magicLink adds passwordless email-link authentication to Better Auth. Configure a sendMagicLink callback to deliver the generated URL, then users can authenticate by following it.
magicLink adds passwordless email authentication to a Better Auth server. When a user requests access, the configured callback receives the recipient, generated URL, token, and request metadata so the application can deliver the link; following it authenticates the user and can redirect to the requested callback URL.
magicLink({ sendMagicLink: async ({ email, token, url, metadata }, ctx) => { /* deliver link */ } })| Name | Type | Description |
|---|---|---|
options | MagicLinkOptions | Configuration object containing sendMagicLink and plugin options such as expiresIn. |
A Better Auth magic-link plugin configuration used by betterAuth.
import { betterAuth } from "better-auth";
import { magicLink } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
magicLink({
sendMagicLink: async ({ email, url }) => {
console.log(`Send to ${email}: ${url}`);
},
}),
],
});Configure the server plugin, then deliver the generated URL through your email provider.
Users should access an application without creating or remembering passwords.
An application uses its own email provider or transactional email service.
A product needs to return users to a requested page after authentication.
A custom message or URL must be used instead of the generated link.
The plugin provides passwordless authentication through an emailed link. The application registers sendMagicLink, which receives the email address and generated URL so it can send the message.
Follow-up: What should a custom delivery implementation preserve? It should deliver the generated URL, or deliberately use the provided token when building a custom URL.
The client calls signIn.magicLink with the user's email address. The server's sendMagicLink callback is then responsible for sending the link to that address.
Follow-up: What happens after the user clicks it? The link authenticates the user and redirects to the callbackURL specified in the sign-in request.
The plugin supports an expiresIn setting expressed in seconds. Its documented default is 300 seconds, or five minutes.
Follow-up: How would you choose a different lifetime? Configure expiresIn in the plugin options, balancing usability against the exposure window of an unconsumed link.
magicLinkClientsignIn.magicLinkverifysendMagicLink