Magic Link authentication system for PhoenixKit.
Magic Link provides passwordless authentication where users receive a secure link via email that allows them to log in without entering a password.
Features
- Passwordless Authentication: Users log in with just their email
- Secure Token System: Uses existing UserToken infrastructure
- Time-Limited Links: Magic links expire after a configurable period
- Optional Integration: Works alongside existing password authentication
- Email Verification: Links are sent to the user's email address
- Auto-Confirmation: Unconfirmed users are automatically confirmed upon magic link use
Usage
# Generate and send magic link
case PhoenixKit.Users.MagicLink.generate_magic_link(email) do
{:ok, user, token} ->
# Send email with magic link
PhoenixKit.Mailer.send_magic_link_email(user, token)
{:ok, user}
{:error, :user_not_found} ->
# Handle unknown email
{:error, :invalid_email}
end
# Verify magic link token
case PhoenixKit.Users.MagicLink.verify_magic_link(token) do
{:ok, user} ->
# Log user in
{:ok, user}
{:error, :invalid_token} ->
# Handle invalid/expired token
{:error, :expired_link}
endSecurity Considerations
- Magic link tokens are single-use (automatically deleted after use)
- Short expiry time (default: 15 minutes) to minimize exposure
- Tokens are hashed before storage in database
- Email address verification ensures link goes to correct recipient
- Integration with existing user session management
Configuration
Magic link expiry can be configured in your application:
# config/config.exs
config :phoenix_kit,
magic_link_for_login_expiry_minutes: 15
Summary
Functions
Gets the number of active magic link tokens for a user.
Cleans up expired magic link tokens.
Checks if magic link authentication is enabled for the application.
Generates a magic link for the given email address.
Generates a magic link URL for the given token.
Revokes all active magic link tokens for a user.
Verifies a magic link token and returns the associated user.
Functions
Gets the number of active magic link tokens for a user.
Useful for debugging or administrative interfaces.
Examples
iex> PhoenixKit.Users.MagicLink.active_magic_links_count(user)
1
Cleans up expired magic link tokens.
This function can be called periodically (e.g., via a scheduled job) to remove expired tokens from the database.
Returns the number of tokens deleted.
Examples
iex> PhoenixKit.Users.MagicLink.cleanup_expired_tokens()
5 # 5 expired tokens were deleted
Checks if magic link authentication is enabled for the application.
This can be used in controllers and views to conditionally show magic link UI.
Examples
iex> PhoenixKit.Users.MagicLink.enabled?()
true
Generates a magic link for the given email address.
This function includes rate limiting protection to prevent token enumeration attacks.
After exceeding the rate limit (default: 3 requests per 5 minutes), subsequent
requests will be rejected with {:error, :rate_limit_exceeded}.
Returns {:ok, user, token} if the user exists and rate limit is not exceeded,
{:error, :user_not_found} if no user is found with that email, or
{:error, :rate_limit_exceeded} if the rate limit has been exceeded.
Examples
iex> PhoenixKit.Users.MagicLink.generate_magic_link("user@example.com")
{:ok, %User{}, "magic_link_token_here"}
iex> PhoenixKit.Users.MagicLink.generate_magic_link("nonexistent@example.com")
{:error, :user_not_found}
iex> PhoenixKit.Users.MagicLink.generate_magic_link("user@example.com")
{:error, :rate_limit_exceeded}
Generates a magic link URL for the given token.
This is a convenience function to construct the full URL that should be included in magic link emails.
Examples
iex> PhoenixKit.Users.MagicLink.magic_link_url("token123")
"http://localhost:4000{prefix}/users/magic-link/token123"
# Where {prefix} is the configured PhoenixKit URL prefix
Revokes all active magic link tokens for a user.
This is useful when:
- Generating a new magic link (only one should be active)
- User logs in via other means (invalidate pending magic links)
- Security concerns require invalidating all passwordless access
Examples
iex> PhoenixKit.Users.MagicLink.revoke_magic_links(user)
:ok
Verifies a magic link token and returns the associated user.
The token is automatically deleted after successful verification (single-use).
If the user's email is not yet confirmed, this function will automatically confirm the user, since clicking the magic link proves email ownership.
Returns {:ok, user} if the token is valid, or {:error, :invalid_token}
if the token is invalid, expired, or already used.
Examples
iex> PhoenixKit.Users.MagicLink.verify_magic_link("valid_token")
{:ok, %User{}}
iex> PhoenixKit.Users.MagicLink.verify_magic_link("invalid_token")
{:error, :invalid_token}