bcsta
bcsta

Reputation: 2307

Django REST framework reset password confirmation not working

I am building a user authentication backend with djano using rest_auth and allauth. This is my api app's urls.py

urlpatterns = [

    path('rest-auth/', include('rest_auth.urls')),

    path('rest-auth/registration/', include('rest_auth.registration.urls')),

    path("account/", include('allauth.urls')),
]

after running server, I am going to rest-auth/password/reset, type in the email and post.

an error occurs saying:

NoReverseMatch at /api/v1/rest-auth/password/reset/
Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.

I found this SO question which helped: NoReverseMatch at /rest-auth/password/reset/

and after looking at the django REST framework official demo: https://django-rest-auth.readthedocs.io/en/latest/demo.html,

I included other endpoints in my url.py as suggested:

urlpatterns = [

    # rest framework authentication: login/logout/signup etc ...
    path('rest-auth/', include('rest_auth.urls')),

    # url endpoint for registration
    path('rest-auth/registration/', include('rest_auth.registration.urls')),

     # url endpoint to confirm email for change of password
     path('password-reset/confirm', TemplateView.as_view(template_name="password_reset_confirm.html"), name="password-reset-confirm"),

     # url link to change password (sent via email)
     path('password-reset/confirm/<uidb64>/<token>/', TemplateView.as_view(template_name="password_reset_confirm.html"),  name='password_reset_confirm'),

    # to handle different account emails (facebook, github, gmail, etc .. )
    path("account/", include('allauth.urls')),
]

where I also included my simple html landing page when resettinthe g password. This works. an email is sent with a confirmation link and the html pages load up. however after I confirm my email in my custom pages, the default page for the django REST auth password reset appears and I have to input the new password there again for the change in password to take effect.

Now at the moment, I would rather just use the Django rest template than my own. so is there a way to not call template_name="password_reset_confirm.html" and go directly to the django default?

or otherwise go directly to the django rest-auth/password/reset/confirm rather than my custom 'password-reset/confirm', which I only implemented to get rid of the error I mentioned.

what is the optimal solution?

Upvotes: 2

Views: 3774

Answers (3)

bcsta
bcsta

Reputation: 2307

Found the answer myself. Daniel Roseman's is a good answer however if you want to use the Django rest framework's rest-auth for resetting the password with email confirmation, the below urlpatterns is the correct one:

from django.urls import include, path
from rest_auth import views

urlpatterns = [    
    path('rest-auth/', include('rest_auth.urls')),

    path('rest-auth/registration/', include('rest_auth.registration.urls')),

    path('rest-auth/password/reset/confirm/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name="password_reset_confirm"),

    path("account/", include('allauth.urls')),
]

The missing knowledge in my case was the views.PasswordResetConfirmView which is the default view for resetting the password in rest-auth

Upvotes: 3

Daniel Roseman
Daniel Roseman

Reputation: 599490

I don't understand why you have done this. There's no point assigning those URLs to TemplateViews, they won't have the right functionality to actually do the reset etc.

I think you are confusing URLs, templates and views. What you actually need to do is to create the relevant URLs, but point them at the existing Django views.

from django.contrib.auth import views

urlpatterns = [
    path('password_reset/', views.PasswordResetView.as_view(), name='password_reset'),
    path('password_reset/done/', views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    path('reset/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('reset/done/', views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]

Upvotes: 1

rootdoot
rootdoot

Reputation: 343

You do not need to add the reverse urls to your urls.py. Take this register function for example. There is a function redirect that will redirect you to the login page when successfully registered

@login_required
def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'An Account has been created for the user  {username}.')
            return redirect('login')
    else:
        form = UserRegisterForm()

    return render(request, 'users/register.html', {'form': form})

Upvotes: 0

Related Questions