Email verification helps confirm that a user owns the email they provide. It improves security and trust by preventing fake or mistyped emails.
Email verification pattern in Flask
from flask import Flask, request, redirect, url_for, render_template_string from itsdangerous import URLSafeTimedSerializer app = Flask(__name__) app.config['SECRET_KEY'] = 'your-secret-key' serializer = URLSafeTimedSerializer(app.config['SECRET_KEY']) def generate_verification_token(email): return serializer.dumps(email, salt='email-confirm-salt') def confirm_verification_token(token, expiration=3600): try: email = serializer.loads(token, salt='email-confirm-salt', max_age=expiration) except Exception: return False return email
Use URLSafeTimedSerializer to create tokens that expire after some time.
Keep your SECRET_KEY safe and unique for your app.
token = generate_verification_token('user@example.com') print(token)
email = confirm_verification_token(token) if email: print(f'Email {email} is verified') else: print('Invalid or expired token')
This Flask app lets a user enter their email to register. It creates a verification link with a token. Visiting the link verifies the email if the token is valid and not expired.
from flask import Flask, request, redirect, url_for, render_template_string from itsdangerous import URLSafeTimedSerializer app = Flask(__name__) app.config['SECRET_KEY'] = 'your-secret-key' serializer = URLSafeTimedSerializer(app.config['SECRET_KEY']) def generate_verification_token(email): return serializer.dumps(email, salt='email-confirm-salt') def confirm_verification_token(token, expiration=3600): try: email = serializer.loads(token, salt='email-confirm-salt', max_age=expiration) except Exception: return False return email @app.route('/register', methods=['GET', 'POST']) def register(): if request.method == 'POST': email = request.form['email'] token = generate_verification_token(email) verify_url = url_for('verify_email', token=token, _external=True) return f'Verification link (send by email): {verify_url}' return '''<form method="post"> Email: <input name="email" type="email" required> <input type="submit" value="Register"> </form>''' @app.route('/verify/<token>') def verify_email(token): email = confirm_verification_token(token) if email: return f'Email {email} has been verified successfully!' else: return 'Verification link is invalid or expired.' if __name__ == '__main__': app.run(debug=True)
In real apps, send the verification link by email instead of showing it on screen.
Tokens expire after 1 hour by default; adjust expiration as needed.
Always validate and sanitize user input to avoid security issues.
Email verification confirms user ownership of an email address.
Use itsdangerous.URLSafeTimedSerializer to create and check tokens.
Send users a link with a token to verify their email safely and simply.
Practice
Solution
Step 1: Understand email verification purpose
Email verification is used to confirm that the user actually owns the email they provided during signup.Step 2: Differentiate from other security tasks
Encrypting passwords and speeding login are different tasks unrelated to email verification.Final Answer:
To confirm that the user owns the provided email address -> Option BQuick Check:
Email verification = Confirm ownership [OK]
- Confusing email verification with password encryption
- Thinking it speeds up login
- Assuming it stores data securely
Solution
Step 1: Identify token generation library
Theitsdangerouslibrary providesURLSafeTimedSerializerto create timed tokens.Step 2: Differentiate from other Flask extensions
flask_sqlalchemymanages databases,flask_loginhandles user sessions, andflask_mailsends emails but does not create tokens.Final Answer:
itsdangerous -> Option CQuick Check:
Token creation = itsdangerous [OK]
- Choosing flask_mail for token creation
- Confusing flask_login with token generation
- Selecting flask_sqlalchemy incorrectly
verify_token(token) return if the token is expired?
from itsdangerous import URLSafeTimedSerializer, SignatureExpired
serializer = URLSafeTimedSerializer('secret-key')
def verify_token(token):
try:
email = serializer.loads(token, max_age=3600)
return email
except SignatureExpired:
return None
Solution
Step 1: Understand token verification logic
The function tries to load the token with a max age of 3600 seconds (1 hour).Step 2: Handle expired token exception
If the token is expired, it raisesSignatureExpired, which is caught and returnsNone.Final Answer:
Returns None -> Option AQuick Check:
Expired token returns None [OK]
- Expecting exception to propagate
- Assuming it returns empty string
- Thinking it returns the email anyway
from itsdangerous import URLSafeTimedSerializer
serializer = URLSafeTimedSerializer('secret-key')
def generate_token(email):
token = serializer.dumps(email)
return token
# Later verification
email = serializer.loads(token, max_age=3600)
Solution
Step 1: Check token generation and usage
The token is generated insidegenerate_tokenbut not stored or passed outside.Step 2: Verify token usage scope
At verification,tokenis used but not defined in that scope, causing a NameError.Final Answer:
Token variable is undefined at verification -> Option AQuick Check:
Undefined token variable causes error [OK]
- Ignoring variable scope for token
- Thinking secret key is missing
- Misusing max_age parameter
Solution
Step 1: Create token with expiration
UseURLSafeTimedSerializerwith a secret key to generate a token that expires after 86400 seconds (24 hours).Step 2: Send email with token link and verify properly
Send the token inside a URL link in the email. Verify the token usingloads()withmax_age=86400to enforce expiration.Final Answer:
Generate token with URLSafeTimedSerializer, send email with token link, verify token with max_age=86400 -> Option DQuick Check:
Token creation + email + 24h expiry = Generate token withURLSafeTimedSerializer, send email with token link, verify token withmax_age=86400[OK]
- Not using tokens in email links
- Ignoring token expiration
- Sending tokens without secret key
Ready to prove it?
Pass the test and this pattern moves unknown
