TL;DR
Let users log in without a password using magic links sent to their email address. This is more secure and easier for users.
How it Works
Instead of asking for a password, we send a unique link to the user’s registered email. Clicking this link automatically logs them in. This relies on verifying the user owns the email address.
Step-by-Step Guide
- Generate a Unique Token: When a user requests passwordless login, create a random, secure token (a long string of characters). This token will be part of the magic link. Use a library or function designed for generating cryptographically secure tokens.
import secrets random_token = secrets.token_urlsafe(32) # Generates a 32-character URL-safe random token - Store the Token: Associate this token with the user’s account in your database, along with an expiry timestamp (e.g., 15 minutes). Crucially, store it securely – hashed if possible.
Example Database Table:
user_id: Integer (Foreign key to users table)token: String (The generated token)expiry_timestamp: Timestamp (When the token expires)
- Create the Magic Link: Build a link that includes the token. This link should point to a specific endpoint on your website designed to handle passwordless login.
base_url = "https://yourwebsite.com/login-magic" token_link = f"{base_url}?token={random_token}" - Send the Email: Send an email to the user’s registered address containing the magic link.
The email should clearly state that this is a login link and will expire soon.
- Verify the Token: When the user clicks the link, your website endpoint needs to verify the token:
- Check Database: Look for the token in your database.
- Expiry Check: Ensure the token hasn’t expired (current timestamp is before
expiry_timestamp). - User Association: Confirm the token is associated with a valid user account.
# Example Python code snippet for verification import datetime def verify_token(token): # Query database for token user = get_user_from_token(token) if user and user.expiry_timestamp > datetime.datetime.now(): return user else: return None - Log the User In: If the token is valid, log the user in automatically.
You can achieve this by creating a session for the user or issuing a JWT (JSON Web Token).
- Invalidate the Token: Once the token has been used to log the user in, immediately invalidate it in your database. This prevents reuse of the link.
# Example Python code snippet for invalidation def invalidate_token(token): # Delete or mark as used in database
Security Considerations
- Token Length: Use sufficiently long tokens (at least 32 characters) to prevent brute-force attacks.
- Expiry Time: Keep the token expiry time short (e.g., 15 minutes).
- HTTPS: Always use HTTPS to protect the magic link in transit.
- Rate Limiting: Implement rate limiting on the number of login requests from a single IP address or email address to prevent abuse.
- Database Security: Protect your database containing tokens with strong security measures.