I cannot wrap my head around this problem. Read a lot of solutions but cannot seem to find the correct combination that works for me.
I want to initiate a users password reset flow from within my (android/iOS) app.
I think I need django-rest-auth
for this to expose an API endpoint something like this:
from rest_auth.views import PasswordResetView urlpatterns = [ path('password/reset/', PasswordResetView.as_view(), name='rest_password_reset'), ]
Now posting to http://127.0.0.1:8000/password/reset/
with a JSON payload of { "email": "test1@test.com" }
gives an error: django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_confirm' not found.
Now, I’m strugeling with the next part. I found that password_reset_confirm is defined in django.contrib.auth
but I do not want to expose the admin-like
interface to the user.
I’d like to use the allauth PasswordResetFromKeyView
.
So, defining password_reset_confirm
as:
path('password/reset/<uidb64>/<token>/', PasswordResetFromKeyView.as_view(), name='password_reset_confirm' ),
Works. An email is send containing a reset URL. But now, following that URL I’m getting another error: PasswordResetFromKeyView.dispatch() missing 2 required positional arguments: 'uidb36' and 'key'
Ok, obvious, changed the password_reset_confirm
path arguments from <uidb64>
and <token>
to <uidb36>
and <key>
.
Than the error moves to password_reset_email.html
because of the arguments in
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
Ok, also changed that to uidb32=uid
and key=token
results in a HTML page displaying “BAD TOKEN”.
Now, I’m completely at a loss. How to configure django-allauth and django-rest-auth so that I can do a rest request to send the email containing a valid URL which the user can use to change his/her password?
Advertisement
Answer
UPDATE: I just saw django-allauth is no longer maintained and that you should switch to: dj-rest-auth. Now the process starts all over again…
Ok, the following works, posting for reference because I have lost an awful lot of time on this.
Pipfile:
[packages] django = "~=3.0" django-allauth = "0.50.0" django-rest-auth = "0.9.5"
urls.py:
from django.contrib import admin from django.urls import path, re_path # Register from allauth.account.views import ConfirmEmailView from rest_auth.registration.views import RegisterView, VerifyEmailView # Password reset from rest_auth.views import PasswordResetView, PasswordResetConfirmView urlpatterns = [ path('admin/', admin.site.urls), re_path(r'^confirm-email/(?P<key>[-:w]+)/$', ConfirmEmailView.as_view(), name='account_confirm_email'), path('user/register/', RegisterView.as_view(), name='rest_register' ), path('user/verify-email/', VerifyEmailView.as_view(), name='rest_verify_email' ), # Password reset path('user/password/reset/', PasswordResetView.as_view(), name='rest_password_reset' ), path('user/password/reset/confirm/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'), ]
I’m able to post to: http://127.0.0.1:8000/user/password/reset/
with a JSON payload of { "email": "test1@test.com" }
.
A Email is generated with an reset URL, clicking this URL brings the user to the browsable API page of Django:
However, this page is not intended to be exposed to the user. So my next question on S.O. is: How to create a custom page for the user to reset his/her password?