Introduction
Django provides built-in views and forms for secure password reset via email.
Key Concepts
Token-based Reset: Secure, one-time use tokens.
Password Reset Views: Built-in CBVs.
Real World Context
Password reset is the most common support request in any web application. A broken reset flow means locked-out users, increased support costs, and lost revenue. Django's built-in views handle token generation, email sending, and secure confirmation, so you do not need to build (and inevitably mis-build) this critical workflow from scratch.
Deep Dive
URL Configuration
python# urls.py from django.contrib.auth import views as auth_views urlpatterns = [ path('password_reset/', auth_views.PasswordResetView.as_view(), name='password_reset'), path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'), path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'), path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'), ]
Email Template
html<!-- templates/registration/password_reset_email.html --> Hello, You requested a password reset for {{ user.email }}. Click here to reset: {{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} This link expires in {{ expiry }} hours.
Token Security
python# settings.py PASSWORD_RESET_TIMEOUT = 3600 # 1 hour (in seconds)
Common Pitfalls
- Revealing whether an email exists: The default
PasswordResetViewintentionally shows the same confirmation page whether the email is registered or not. Customizing it to say "email not found" leaks user enumeration data. - Setting
PASSWORD_RESET_TIMEOUTtoo long: The default is 3 days (259200 seconds). For most apps, 1 hour is sufficient. Longer windows increase the risk of token interception. - Not configuring an email backend: Without
EMAIL_BACKENDset (or set to the console backend in production), users never receive the reset email and assume the feature is broken.
Best Practices
- Use HTTPS: For all reset links.
- Limit token lifetime: Default 3 days is too long.
- Rate limit requests: Prevent email flooding.
Summary
Use Django's built-in password reset views. Configure short token timeout. Always use HTTPS for reset links.