TL;DR
Let users log in without passwords by clicking a unique link sent to their email address after they initiate the process on an external website. This guide explains how to set it up.
How It Works
The basic flow is:
- User starts login on your external site (e.g., a marketing page).
- Your site asks for the user’s email address.
- Your site generates a unique, time-limited token and creates a link containing it.
- Your site sends an email to the provided address with this magic link.
- The user clicks the link in their email.
- Your server validates the token. If valid, log the user in.
Step-by-Step Guide
This guide assumes you have a basic web application with an email sending capability.
1. Choose a Token Generation Method
You need a secure way to create unique tokens. Here are some options:
- UUIDs: Universally Unique Identifiers (UUIDs) are good for uniqueness.
- Random Strings: Generate random strings of sufficient length (e.g., 32 characters).
- Cryptographically Secure Tokens: Use a library to generate tokens designed for security.
Example using Python:
import secrets
import string
def generate_token(length=32):
alphabet = string.ascii_letters + string.digits
return ''.join(secrets.choice(alphabet) for i in range(length))
token = generate_token()
print(token)
2. Store Tokens Securely
You need a place to store the tokens and associate them with users.
- Database: The most common approach. Store the token, user ID, expiry timestamp, and potentially other metadata (e.g., IP address).
- Redis: A fast in-memory data store suitable for short-lived tokens.
Important considerations:
- Expiry Time: Set a reasonable expiry time for the token (e.g., 15 minutes).
- One-Time Use: Mark the token as used after successful login to prevent reuse.
3. Create the Magic Link
When the user submits their email address, generate a token and create a link that includes it.
base_url = "https://yourwebsite.com/login" # Replace with your actual URL
token = generate_token()
expiry_time = datetime.now() + timedelta(minutes=15)
db.insert_token(user_id, token, expiry_time) # Store in database
magic_link = f"{base_url}?token={token}"
send_email(email_address, "Login Link", f"Click here to log in: {magic_link}")
4. Handle the Magic Link Click
When a user clicks the link, your server needs to validate it.
- Extract Token: Get the token from the URL query parameters (e.g.,
request.args.get('token')). - Validate Token: Check if the token exists in your database/Redis and hasn’t expired.
- Log In User: If valid, retrieve the associated user ID and log them in (e.g., create a session or issue a JWT).
- Mark Token as Used: Update the token record to prevent reuse.
Example (simplified):
token = request.args.get('token')
token_record = db.get_token(token)
if token_record and token_record['expiry_time'] > datetime.now():
user_id = token_record['user_id']
db.mark_token_as_used(token)
# Log user in (e.g., create session)
session['user_id'] = user_id
return redirect('/dashboard')
else:
return "Invalid or expired link"
5. Security Considerations
- HTTPS: Always use HTTPS to protect the token in transit.
- Token Length: Use sufficiently long tokens to make them difficult to guess.
- Expiry Time: Keep expiry times short.
- Rate Limiting: Limit the number of login attempts per email address to prevent abuse.
- IP Address Logging: Consider logging the IP address associated with token creation for security auditing.

