DEV Community

Richard
Richard

Posted on • Edited on

Django Diaries - Password Reset Email

This is part 5 of the Django Diaries, We will be sending password reset emails to users if they forget their password.

The code from Corey Schafer's Tutorial can be found here (Number 12). This blog series is entirely based on what I learned from here:

Django has it's own functionality to generate a secure token for resetting a password. Django also encrypts all the passwords automatically.

The fist thing we need to do is to set up the URLs in the main project 'urls.py'. There are quite a few default views Django needs. We need to add these to the URLs.

from django.contrib.auth import views as auth_views

urlpatterns = [
    path("password-reset", auth_views.PasswordResetView.as_view( template_name="users/password_reset.html"), name="password_reset"),
    path("password-reset/done/", auth_views.PasswordResetDoneView.as_view( template_name="users/password_reset_done.html"), name="password_reset_done"),
    path("password-reset-confirm/<uidb64>/<token>", auth_views.PasswordResetConfirmView.as_view( template_name="users/password_reset_confirm.html"), name="password_reset_confirm"),
    path("password-reset-complete/", auth_views.PasswordResetCompleteView.as_view( template_name="users/password_reset_complete.html"), name="password_reset_complete")
]
Enter fullscreen mode Exit fullscreen mode

We also need a bunch of templates that django can use. 'users/password_reset.html' is a form that the user fills out to send a rest password email.
Alt Text

We then have the password reset done template which is where the user is send to when the user submits the form, it would tell them that an email has been sent and they should follow the instructions in their inbox.

users/password_reset_done.html

Alt Text

Another route & template that is needed is the 'password_reset_confirm'. This route requires the uidb64 token of the user and a token, so we put this in the route. These are used to identify the user and are passed in by django from the link in the email. This is the route that Django follows when the user submits the first form and here is asked if they are sure they want to reset their password.

Alt Text

Now we need to specify the email client, so django can send an email. I will use Gmail. The first setting tells django that it should be using and SMTP (Simple mail transfer protocol). We then set a email host in this case gmail. If you need other Email Clients see the django docs. We then set the gmail post which is 587 and tell it to use TLS, this is for security.

Finally you need to add your email details, I added my email address to my computers environment variables and called it EMAIL_USER. For the password I recommend visiting https://myaccount.google.com/security and turning on Two-Factor Authentication. This then allows you to set up an app password so you don't have to use your real password. Google will generate a password for you which you can use.

settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = "smtp.gmail.com"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.environ.get('EMAIL_USER')
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_PASS')
Enter fullscreen mode Exit fullscreen mode

Now you should be able to send an email. This will send you a link with a form to set a new password. This will be '/password-reset-confirm/UID/token'

The final route is the 'password_reset_complete' which is where django takes the user when the password has been reset.
Alt Text

Finally you can add a 'forgot password' link on the login page.


✨If you would like to follow my day to day development journey be sure to check my Instagram.

Top comments (3)

Collapse
 
imoneofthejack profile image
Jack

Thank you for your password email reset tutorial. It's nice and clear.

Collapse
 
utkichaps profile image
Utkarsh Chhapekar

Great tutorial! A small typo in your settings.py - it should be EMAIL_PORT instead of EMAIL_POST

Collapse
 
merichard123 profile image
Richard

Oh Thank you!! I wouldn't have noticed that 😂

Glad you enjoyed it.