python-3.xdjangopasswordsresetdjango-allauth

Django REST Auth password reset email sends API URL instead of frontend React URL


I am using dj-rest-auth with Django as the backend and React.js as the frontend. I want the password reset email to point to my React frontend URL, not the default API endpoint.

Sending: http://localhost:8000/api/auth/password/reset/confirm/{uidb64}/{token}

Correct url: https://my-domain.com/password-reset/confirm/{uidb64}/{token}

.env

BASE_URL=https://my-domain.com

settings.py

REST_AUTH = {
    'PASSWORD_RESET_CONFIRM_URL': env('BASE_URL')+'/password-reset/confirm/{uidb64}/{token}',
    'PASSWORD_RESET_SERIALIZER': 'users.serializers.CustomPasswordResetSerializer',
}

urls.py

from django.urls import path, re_path
from .views import (
    CustomPasswordResetView
)
from dj_rest_auth.views import LogoutView, PasswordResetConfirmView, PasswordResetView

urlpatterns = [
    path('password/reset/', CustomPasswordResetView.as_view(), name='rest_password_reset'),
    path('password/reset/confirm/<uidb64>/<token>/',
         PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
]

views.py

class CustomPasswordResetView(PasswordResetView):
    serializer_class = CustomPasswordResetSerializer

serializers.py

class CustomPasswordResetSerializer(DjRestAuthPasswordResetSerializer):
    def get_email_options(self):
        return {
            'email_template_name': 'registration/password_reset_email.html',
            'extra_email_context': {
                'password_reset_url': settings.REST_AUTH['PASSWORD_RESET_CONFIRM_URL'],
            }
        }

password_reset_email.html

# failed to test both styles of URL
<a href="{{ password_reset_url }}">{{ password_reset_url }}</a>
<a href="{{ base_url }}/password-reset/confirm/{{ uid }}/{{ token }}">{{ base_url }}/password-reset/confirm/{{ uid }}/{{ token }}</a>

Problem: • The email still sends the default API URL. • I want it to send my custom React frontend URL. • I want to use a custom email template.

I have tried: • PASSWORD_RESET_CONFIRM_URL in settings • extra_email_context in custom serializer • Modifying the template with {{ base_url }}

…but the reset URL in the email still points to the backend API.

Question: How can I configure dj-rest-auth to send a custom frontend URL in the password reset email, using my custom email template?


Python                    3.11.2
django-sslserver          0.22
djangorestframework       3.15.2
dnspython                 2.7.0
ipython                   8.12.3
mysql-connector-python    9.1.0
opencv-python             4.10.0.84
python-dateutil           2.9.0.post0
python-dotenv             1.0.1
python-jose               3.5.0
python-multipart          0.0.20


Solution

  • To use your app URL instead of the api URL, you'll have to write a custom password reset serializer and override the get_email_options:

    from dj_rest_auth.serializers import PasswordResetSerializer
    
    from decouple import config # or use env as you used
    
    
    BASE_URL = config('BASE_URL')
    
    
    def custom_url_generator(request, user, temp_key):
        return f'{BASE_URL}?token={temp_key}'
    
    
    class CustomPasswordResetSerializer(PasswordResetSerializer):
        def get_email_options(self):
            return {
                'url_generator': custom_url_generator
            } 
    

    This allows allows customizing the URL that will be sent to your users while using the default email template provided by allauth.

    To use a custom email template, you can override the original email structure:
    In your project's root directory, create a templates > account > email directory. Now add a base_message.txt and password_reset_key_message.txt files. You can take the structure from the official allauth templates directory. Now if you leave the {{ password_reset_url }} in your password_reset_key_message.txt intact, its value should be taken from the custom_url_generator we defined before.

    Refer to this comment on a similar issue.