Django Diaries - Password Reset Email
Tags: wedev, django
Published: 2020-08-09 15:58:40

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](https://github.com/CoreyMSchafer/code_snippets/tree/master/Django_Blog) (Number 12). This blog series is entirely based on what I learned from here:
{% youtube -tyBEsHSv7w %}


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.
```python
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")
]
```
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](https://dev-to-uploads.s3.amazonaws.com/i/osr240z6r4uiw239jw0w.jpg)

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](https://dev-to-uploads.s3.amazonaws.com/i/lnsz622w4ciobefk3v1c.jpg)

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](https://dev-to-uploads.s3.amazonaws.com/i/jkd42dw60klzu3e5jwut.jpg) 

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
```python
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')
```
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](https://dev-to-uploads.s3.amazonaws.com/i/6qh1hz9hxqfdvnjswppt.jpg)

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](https://www.instagram.com/me_richard1/).