App Logo
Plugins

Magic Link Plugin

Passwordless authentication using email-based magic links

Overview

The Magic Link plugin provides passwordless authentication using email-based magic links. Users receive a secure link via email that they can click to sign in without passwords, offering a seamless and secure authentication experience.

Features

  • Passwordless Authentication — Sign in via email without passwords
  • Secure Token-Based Verification — Cryptographically secure tokens with configurable expiration
  • Configurable Expiration — Set custom token expiration times
  • Optional Sign-Up Prevention — Prevent sign-ups for magic links
  • Custom Email Sending — Support for custom email sending functions
  • Callback URL Support — Redirect users to custom URLs after verification

Configuration

Standalone Mode

[plugins.magic_link]
enabled = true
expires_in = "15m"
disable_sign_up = false

Library Mode

import (
	"time"

	authulamodels "github.com/Authula/authula/models"
	magiclinkplugin "github.com/Authula/authula/plugins/magic-link"
	magiclinkplugintypes "github.com/Authula/authula/plugins/magic-link/types"
)

magiclinkplugin.New(magiclinkplugintypes.MagicLinkPluginConfig{
	Enabled:       true,
	ExpiresIn:     15 * time.Minute,
	DisableSignUp: false,
	SendMagicLinkVerificationEmail: func(
		params magiclinkplugintypes.SendMagicLinkVerificationEmailParams,
		reqCtx *authulamodels.RequestContext,
	) error {
		// Optionally handle sending email here...
		return nil
	},
})

Configuration Options

OptionTypeDefaultDescription
expires_intime.Duration"15m"Magic link token expiration time
disable_sign_upboolfalsePrevent new user registration

API Reference

MethodEndpointDescription
POST/magic-link/sign-inSend magic link email to user
GET/magic-link/verifyVerify token from email link
POST/magic-link/exchangeExchange verified token for user session

Sign In

Sends a magic link email to the user.

POST /magic-link/sign-in

Request body:

{
  "email": "user@example.com",
  "name": "John Doe",
  "callback_url": "https://yourapp.com/callback"
}

Verify

Verifies the token from the email link. If callback_url is provided, redirects with the token. Otherwise returns the token in JSON.

GET /magic-link/verify?token=<token>&callback_url=<url>

Exchange

Exchanges the verified token for user session and authentication.

POST /magic-link/exchange

Request body:

{
  "token": "<verification_token>"
}

Database Schema

The Magic Link plugin does not create any database tables.


Plugin Capabilities

The Magic Link plugin provides no hooks or capabilities.


Flow Steps

1. Request Sign-In — Client calls /magic-link/sign-in with user's email address.

2. Magic Link Sent — A secure token is generated and sent to the user's email address.

3. User Clicks Link — User clicks the magic link in the email, which calls /magic-link/verify.

4. Token Verified — The token is verified for validity and expiration.

5. Exchange for Session — Client calls /magic-link/exchange with the verified token to establish a session.

6. Session Created — User is authenticated with an active session.


Client Plugin

If you're using the Authula SDK, add the plugin to the SDK like so:

import { createClient } from "authula";
import { MagicLinkPlugin } from "authula/plugins";

export const authulaClient = createClient({
  url: "http://localhost:8080/auth",
  plugins: [
    // other plugins...
    new MagicLinkPlugin(),
  ],
});

Security Recommendations

  • Short Expiration Times — Use short expires_in values (15 minutes or less) to minimize token exposure window
  • Single-Use Tokens — Tokens are automatically marked as used after verification to prevent replay attacks
  • HTTPS Required — Always use HTTPS in production to protect magic links in transit
  • Rate Limiting — Consider rate limiting the /magic-link/sign-in endpoint to prevent email flooding attacks
  • Email Verification — For new user registration, consider additional verification steps before allowing account creation
  • Token Hashing — Tokens are automatically hashed before storage; never log or expose raw tokens
  • Disable Sign-Up — Set disable_sign_up = true for applications that do not want to allow new user registration via magic links

On this page