In my Django Rest Framework, the users request to reset the password and when the email is received everytime the link is clicked it shows a message Password reset unsuccessful The password reset link was invalid, possibly because it has already been used. Please request a new password reset.
here is what I have tried API urls.py
app_name = 'api'
router = routers.DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
urlpatterns = [
path('', include(router.urls)),
path('dj-rest-auth/', include('dj_rest_auth.urls')),
path('dj-rest-auth/registration/', include('dj_rest_auth.registration.urls')),
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
# path('password_reset/',PasswordResetView.as_view(), name='password_reset'),
# path('password_reset_confirm/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
]
here is the users app urls.py if required:
app_name = 'users'
urlpatterns = [
path('password-reset/', auth_views.PasswordResetView.as_view(template_name='users/password_reset.html', success_url=reverse_lazy('users:password_reset_done')), 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',success_url=reverse_lazy('users:password_reset_done'),post_reset_login=True),name='password_reset_confirm',),
path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view(template_name='users/password_reset_complete.html'),name='password_reset_complete'),
]
My question is: Why do I keep receiving invalid links and how can I fix it?
In different questions I got answers to add the commented paths but still did not work. Any suggestions on how to fix it ?
EDIT 19/05/2023 -- If you are using all-auth in addition to dj-rest-auth, the solution specified in the tutorial linked below won't work as dj-rest-auth uses the allauth form to send mails instead of it's own code (which is what the tutorial relies on), instead check this out for updating the mail.
One quick and dirty way is to take the link that you get in the mail, and map it to the password reset view of dj-rest-auth explicitly. For eg -- if you receive http://localhost:8000/dj-rest-auth/reset/q/bocmhi-aec6f621a81d201ba7e71ae6a85c14cb/ in mail, map the view as follows in urls.py:-
Please note that 'get' won't work on that link, so instead you'll be taken to DRF endpoint view where you will be asked for Uid (q in the example),token (bocmhi-aec6f621a81d201ba7e71ae6a85c14cb in the example), and passwords 1 and 2 (essentially new password and confirm pwd). Fill them and post, and it should work ok.
Since you are using a custom template/view, you can update the link received in the mail by following this tutorial. Update it to point to your custom url pointing to your view/template, retrieve the UID and token from the URL, ask user for new password and then post to the original dj-rest-auth endpoint with those values and convey the result. You can do this exercise using a different front-end framework as well, as long as you post the 4 necessary fields -- UID,token,New password1 and New password2 -- to the endpoint .
This works even in case you are using allauth with dj-rest-auth. One imp side note if it helps anyone -- allauth uses base36 encoding to encode user ids (26 in binary = q in base 36), so dj-rest-auth checks whether it is installed and uses it's encoding accordingly.