Magic Links
ConsentKeys uses passwordless authentication via magic links instead of traditional passwords. This approach provides better security and user experience.
What Are Magic Links?
A magic link is a secure, time-limited URL sent to a user's email that allows them to authenticate without entering a password. When clicked, it automatically logs the user in.
Example magic link:
https://pseudoidc.consentkeys.com/verify-email?token=eyJhbGciOiJIUzI1NiIs...
Why Magic Links?
Security Benefits
- No Password Reuse: Users can't reuse weak passwords across sites
- No Password Breaches: No passwords to steal or leak
- Phishing Resistant: Links are single-use and time-limited
- Email Verification: Proves email ownership automatically
User Experience Benefits
- No Password to Remember: Reduces friction for users
- Faster Login: One click instead of typing credentials
- No Password Reset Flow: Eliminates "forgot password" frustration
- Cross-Device Friendly: Easy to authenticate on any device
How It Works
Token Security
Magic link tokens are designed with multiple security layers:
Token Generation
// Pseudocode - internal ConsentKeys implementation
const token = {
email: 'user@example.com',
clientId: 'ck_...',
redirectUri: 'https://...',
state: '...',
nonce: '...',
exp: Date.now() + (15 * 60 * 1000), // 15 minutes
iat: Date.now(),
jti: generateUniqueId(), // Prevents reuse
};
const signedToken = jwt.sign(token, SECRET_KEY);
Token Properties
- Single-use: Each token can only be used once
- Time-limited: Expires after 15 minutes
- Cryptographically signed: Cannot be tampered with
- Email-bound: Tied to a specific email address
- Client-bound: Tied to your specific application
Token Validation
When a user clicks the magic link, ConsentKeys validates:
- ✅ Token signature is valid
- ✅ Token has not expired
- ✅ Token has not been used before
- ✅ Email matches the token
- ✅ Client ID matches the token
If any check fails, the token is rejected.
Implementation
Requesting a Magic Link
When a user enters their email:
POST /request-magic-link
Content-Type: application/json
{
"email": "user@example.com",
"client_id": "ck_your_client_id",
"redirect_uri": "https://yourapp.com/callback",
"scope": "openid profile email",
"state": "csrf_protection_token",
"nonce": "replay_protection_token"
}
Response:
{
"message": "Magic link sent successfully",
"email": "user@example.com"
}
Email Content
The user receives an email like this:
Subject: Sign in to YourApp
Hello,
Click the button below to sign in to YourApp:
[Sign In to YourApp]
Or copy and paste this link:
https://pseudoidc.consentkeys.com/verify-email?token=...
This link will expire in 15 minutes.
If you didn't request this, you can safely ignore this email.
Verification Process
When the user clicks the link:
GET /verify-email?token=eyJhbGciOiJIUzI1NiIs...
Success Flow:
- Token validated → User redirected to consent screen
- User approves → Redirect to your app with auth code
- Your app exchanges code for tokens
Error Flow:
{
"error": "invalid_token",
"error_description": "The magic link has expired or is invalid."
}
User Experience Patterns
First-Time User
1. User enters email
2. Sees "Check your email" message
3. Opens email client
4. Clicks magic link
5. Sees consent screen
6. Clicks "Allow"
7. Redirected to your app (logged in)
Returning User (Same Device)
1. User enters email
2. Sees account chooser (recognizes device)
3. Clicks their account
4. Redirected to your app (logged in)
(No email needed - session exists!)
Returning User (New Device)
1. User enters email
2. Sees "Check your email" message
3. Clicks magic link
4. Consent screen skipped (already approved)
5. Redirected to your app (logged in)
Rate Limiting
To prevent abuse, magic link requests are rate-limited:
- 20 requests per hour per email address
- 100 requests per hour per IP address
Exceeding limits returns:
{
"error": "too_many_requests",
"error_description": "Too many magic link requests. Please try again later."
}
Customization
Email Templates
You can customize the magic link email through the Developer Portal:
- Brand logo: Display your app's logo
- Brand colors: Match your app's theme
- Custom text: Add additional context
- Sender name: Display your app name
Link Expiration
Default expiration is 15 minutes. Contact support to adjust this for your use case.
Troubleshooting
"Magic link expired"
Cause: User waited more than 15 minutes to click the link
Solution: Request a new magic link
"Magic link already used"
Cause: Token was already consumed (clicked twice)
Solution: Request a new magic link
"Email not received"
Possible causes:
- Email in spam folder
- Incorrect email address
- Rate limit exceeded
Solutions:
- Check spam folder
- Verify email address spelling
- Wait before requesting again
"Invalid token"
Possible causes:
- Token was tampered with
- Email client modified the URL
- Token signature invalid
Solution: Request a new magic link
Best Practices
1. Show Clear Instructions
function LoginSuccess() {
return (
<div>
<h2>Check your email</h2>
<p>
We sent a magic link to <strong>{email}</strong>
</p>
<p>Click the link in the email to sign in.</p>
<p>
Didn't receive it? Check your spam folder or{' '}
<button onClick={resendMagicLink}>request a new link</button>
</p>
</div>
);
}
2. Handle Expired Tokens Gracefully
function TokenExpired() {
return (
<div>
<h2>Link Expired</h2>
<p>This magic link has expired for security reasons.</p>
<button onClick={() => window.location.href = '/login'}>
Request a new link
</button>
</div>
);
}
3. Support Deep Linking
Preserve the user's intended destination:
// Before redirecting to login
sessionStorage.setItem('return_to', window.location.pathname);
// After authentication
const returnTo = sessionStorage.getItem('return_to') || '/dashboard';
window.location.href = returnTo;
4. Mobile App Considerations
For mobile apps, use deep links to return to the app:
redirect_uri=myapp://auth/callback
Security Considerations
Email Account Security
Since authentication is email-based, email account security is critical:
- Encourage 2FA: Remind users to enable 2FA on their email
- Detect Suspicious Activity: Monitor for unusual login patterns
- Session Management: Implement appropriate session timeouts
Link Interception
Magic links in emails are vulnerable to:
- Email forwarding: Users might forward the email
- Email backups: Links might be stored in backups
- Email client previews: Some clients preview links
Mitigations:
- Short expiration times (15 minutes)
- Single-use tokens
- IP address validation (optional)
Next Steps
- Understand the complete Authentication Flow
- Learn about Scopes and Claims
- Check the API Reference