Authsome

Magic Links

Passwordless email sign-in with time-limited magic link tokens.

The magiclink plugin provides passwordless sign-in via a one-time link sent to the user's email address. No password is required. Users click the link and are immediately authenticated with a full session.

Magic links are ideal for:

  • Applications where users sign in infrequently (reducing password friction)
  • B2B tools where users may not remember a password set months ago
  • Supplementing password auth as an alternative sign-in method

Setup

import (
    "github.com/xraph/authsome"
    "github.com/xraph/authsome/plugins/magiclink"
    "github.com/xraph/authsome/bridge/maileradapter"
)

mailer := maileradapter.NewResend("re_your_resend_api_key")

eng, err := authsome.New(
    authsome.WithStore(store),
    authsome.WithMailer(mailer),         // required: magic links are sent via email
    authsome.WithPlugin(magiclink.New(magiclink.Config{
        TokenTTL:    15 * time.Minute,   // how long the link stays valid
        AutoCreate:  true,               // create user on first sign-in if not found
    })),
)

A Mailer bridge is required. If no mailer is configured, magic link requests succeed on the server side (the token is generated) but the email is never delivered. Always configure a mailer before deploying to production.

How it works

Request a magic link: The user submits their email address.

POST /v1/auth/magic-link/request

{"email": "alice@example.com", "app_id": "myapp"}

The engine:

  1. Looks up the user by email. If AutoCreate: true and the user does not exist, creates a new user account automatically.
  2. Generates a cryptographically random token.
  3. Stores the token with a TTL (default 15 minutes).
  4. Calls the Mailer bridge to deliver the email.

The response is always 200 OK regardless of whether the email exists, preventing email enumeration.

User clicks the link: Your application receives the request with the token in the URL.

The link format is determined by your application. A typical pattern:

https://myapp.com/auth/magic-link?token=ml_abc123xyz&app_id=myapp

Your frontend extracts the token and calls the confirm endpoint.

Confirm the token: Exchange the token for a session.

POST /v1/auth/magic-link/confirm

{"token": "ml_abc123xyz", "app_id": "myapp"}

On success, a full user + session pair is returned:

{
  "user": {"id": "ausr_01j9...", "email": "alice@example.com", ...},
  "session": {"token": "a3f8c9d4...", "refresh_token": "d72b1ef8...", ...}
}

The token is consumed (one-time use) and invalidated after use.

Configuration

type Config struct {
    // TokenTTL is the lifetime of the magic link token (default: 15 minutes).
    TokenTTL time.Duration

    // AutoCreate creates a new user account if the email is not found.
    // Default: false — returns 404 for unknown emails.
    AutoCreate bool

    // RedirectURL is the base URL for the magic link.
    // The token is appended as a query parameter: RedirectURL + "?token=" + token.
    // Required if you want the plugin to construct the link automatically.
    RedirectURL string
}

Email template customization

The magic link email is sent through the Mailer bridge. To customize the email content, implement the bridge.Mailer interface and return your own HTML/text for the magic_link template type:

type myMailer struct{}

func (m *myMailer) Send(ctx context.Context, msg bridge.MailMessage) error {
    switch msg.Template {
    case "magic_link":
        // msg.Data["token"] contains the magic link token.
        // msg.Data["link"]  contains the full redirect URL (if RedirectURL is configured).
        return sendCustomEmail(msg.To, msg.Data)
    }
    return nil
}

The bridge.MailMessage struct contains:

type MailMessage struct {
    To       string            // recipient email
    Template string            // "magic_link", "verify_email", "reset_password"
    Subject  string            // suggested subject line
    Data     map[string]string // template variables
}

Security considerations

  • Tokens are single-use. Once a token is consumed, it cannot be reused. Re-requesting a magic link generates a new token and invalidates all previous tokens for that email.
  • Tokens expire. The default TTL is 15 minutes. Set a shorter TTL for higher-security applications.
  • Tokens are not guessable. Tokens are generated using crypto/rand and are URL-safe base64-encoded.
  • Rate limiting. Use RateLimitConfig.SignInLimit to prevent abuse. Magic link requests that succeed server-side but fail email delivery are counted toward the rate limit.

API routes

MethodPathDescription
POST/magic-link/requestGenerate a magic link token and send email
POST/magic-link/confirmConfirm the token and return a session

On this page