Magic links provider¶
Passwordless sign-in via a one-time link emailed to the user. Unknown emails are auto-registered on first use.
from fastauth.providers.magic_links import MagicLinksProvider
provider = MagicLinksProvider() # default max_age=900 (15 min)
provider = MagicLinksProvider(max_age=600) # 10-min request TTL
max_age controls how long a magic-link login-request token is valid (stored as type "magic_link_login_request"). Requires the email extra for SMTP, or any EmailTransport. token_adapter is required — MagicLinksProvider.send_login_request raises ConfigError("token_adapter is required for magic links") on first login attempt otherwise.
Endpoints¶
| Method | Path | Auth | Request | Response |
|---|---|---|---|---|
| POST | /auth/magic-links/login |
— | {email} |
{message: "Magic link sent — check your email"} |
| GET | /auth/magic-links/callback |
— | ?token=... |
cookie: MessageResponse; json: TokenResponse |
Flow¶
sequenceDiagram
participant U as User
participant A as App
participant T as TokenAdapter
U->>A: POST /auth/magic-links/login {email}
alt email unknown
A->>A: create user with hashed_password=None
A->>A: assign default_role (if role_adapter)
A->>A: fire on_signup
end
A->>T: store hash(token), TTL=max_age
A-->>U: 200 "Magic link sent — check your email"
A-->>U: email with {base_url}/auth/magic-links/callback?token=...
U->>A: GET /auth/magic-links/callback?token=...
A->>T: consume hash(token) (atomic)
alt not email_verified
A->>A: set email_verified=True, fire on_email_verify
end
A->>A: fire allow_signin(user, "magic_link"), 403 if False
A->>A: issue tokens, cookie mode sets cookies
A-->>U: cookie: MessageResponse, json: TokenResponse
Auto-registration¶
Unknown emails are auto-registered with hashed_password=None. This means any email can create an account. If that is not acceptable, you can:
- gate it in
allow_signin(user, "magic_link")returningFalsefor freshly created users (the hook receives the post-creationUserData), or - not expose the magic-links router while keeping credentials.
A pre-create hook is not currently available. (needs maintainer clarification on whether one will be added)
Hooks¶
on_signup(only on auto-registration)on_magic_link_sent(after the email is sent)on_email_verify(ifemail_verified=Falseat callback)allow_signin(user, "magic_link")—False→403on_signin— JSON mode only; in cookie mode it is not fired. (needs maintainer clarification)
Common mistakes¶
ConfigError: token_adapter is required for magic links—MagicLinksProvider.send_login_requestraises this at the first login attempt iftoken_adapterisNone.- Forgetting
base_url— the link in the email points atlocalhost:8000. debug=Truein production — relaxes cookie security.- Multi-worker SMTP —
SMTPTransportis async and stateless; safe under workers.