Django Rest Framework — How to Edit Reset Password Link in Dj-Rest-Auth with Dj-AllAuth installed

Emmanuel Etentuk
4 min readJan 12, 2022

Introduction

While working on a project I encountered issues changing the password reset link provided by Dj-rest-auth. I searched online and followed the documentation and configuration options provided but I was unable to truly find what I was searching for.

It turns out that when Dj-allauth is installed along with Dj-rest-auth the Password reset form used by the Password Reset Serializer comes from Dj-allauth. This reset form causes all changes to the Dj-rest-auth Password Reset Serializer to be ignored.

I will show you how to work around this configuration and change the password_reset_url in this article.

This article is aimed at people facing this specific problem, so if you are reading this then I believe you have completed all the necessary steps to get a project up and running. But if you would like to see how to set up Dj-rest-auth, consider checking out this Article Django Rest Framework Authentication with Dj-Rest-Auth by Jekayinoluwa Olabemiwo which outlines and dives into the process.

There are two methods of changing the Password Reset Link while using Dj-rest-auth.

  1. Configuring Password Reset Serializer options in Dj-rest-auth.
  2. Configuring the AllAuthPasswordResetForm

Dj-rest-auth Password Reset Serializer

This step involves overriding the Password Reset Serializer used by Dj-rest-auth. The aim is to create a custom email that will be used by the serializer when sending out the reset email.

Numerous resources are online already for this step. A couple of them are below;

AllAuthPasswordResetForm

If you are looking to only have a custom password reset email, you will need to create a templates folder with the following directory structure app_name/templates/account/email/ in your project folder. Within the email directory, you can then create a new text file called password_reset_key_message.txt .

The next step is to add the new templates directory in settings.

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'app_name/templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

With this, you can edit the contents of the password reset email.

To edit the subject, create a new file within the email directory called password_reset_key_subject.txt and provide the content you would like to show.

The default contents for these files can be found here Dj-Allauth Templates.

Now you would expect that changing the password reset link within the email would solve this right? Nope, the problem that arises is that the user id and token which are part of the password reset link are not passed down as variables to the reset email. Due to this, changing the password reset link in the email will change the link shown in the email but with the new link, you will be unable to reset the password because the user id and token will be missing.

The Password Reset Serializer form used by Dj-rest-auth when Dj-allauth is present is AllAuthPasswordResetForm . This is gotten by calling the password_reset_form_class method. This is located in Dj-rest-auth/serializers. The method is given below.

def password_reset_form_class(self):
if 'allauth' in settings.INSTALLED_APPS:
return AllAuthPasswordResetForm
else:
return PasswordResetForm

As you can see above, the AllAuthPasswordResetForm takes precedence over the default Django PasswordResetForm.

The password_reset_url which is used by the default password_reset_key_message.txt is created in the AllAuthPasswordResetForm .

The solution I found was to create a custom AllAuthPasswordResetForm and then edit the password_reset_url used within this custom form. Then, pass this form to the custom PasswordResetSerializer for Dj-rest-auth.

from allauth.account.utils import (filter_users_by_email, user_pk_to_url_str, user_username)
from allauth.utils import build_absolute_uri
from allauth.account.adapter import get_adapter
from allauth.account.forms import default_token_generator
from allauth.account import app_settings
from dj_rest_auth.serializers import PasswordResetSerializer
class CustomAllAuthPasswordResetForm(AllAuthPasswordResetForm):

def clean_email(self):
"""
Invalid email should not raise error, as this would leak users
for unit test: test_password_reset_with_invalid_email
"""
email = self.cleaned_data["email"]
email = get_adapter().clean_email(email)
self.users = filter_users_by_email(email, is_active=True)
return self.cleaned_data["email"]

def save(self, request, **kwargs):
current_site = get_current_site(request)
email = self.cleaned_data['email']
token_generator = kwargs.get('token_generator', default_token_generator)

for user in self.users:
temp_key = token_generator.make_token(user)

path = f"custom_password_reset_url/{user_pk_to_url_str(user)}/{temp_key}/"
url = build_absolute_uri(request, path)
#Values which are passed to password_reset_key_message.txt
context = {
"current_site": current_site,
"user": user,
"password_reset_url": url,
"request": request,
"path": path,
}

if app_settings.AUTHENTICATION_METHOD != app_settings.AuthenticationMethod.EMAIL:
context['username'] = user_username(user)
get_adapter(request).send_mail(
'account/email/password_reset_key', email, context
)

return self.cleaned_data['email']
class MyPasswordResetSerializer(PasswordResetSerializer):

def validate_email(self, value):
# use the custom reset form
self.reset_form = CustomAllAuthPasswordResetForm(data=self.initial_data)
if not self.reset_form.is_valid():
raise serializers.ValidationError(self.reset_form.errors)

return value

Lastly, you will need to declare that this is the serializer you will like to use in the settings file for your Django project.

REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER': 'app_name.path_to_serializer.MyPasswordResetSerializer'
}

With this, you will be able to change the password reset link as you please.

Conclusion

The aim of this blog is to show you where the variables which are passed into the password_reset_key_message.txt file are created and how to edit these variables.

With this as a foundation, I hope you are able to handle future challenges regarding the emails which are sent out by Dj-rest-auth with ease.

Thank you for making it this far and taking the time to read this article.

--

--

Emmanuel Etentuk

I am a developer interested in learning new things and gaining freedom in the world of Computer Programming through Knowledge.