A reminder when I'm implementing an API in Django using the rest framework and trying to implement a user password reset feature
Django has a powerful auth feature called django.contrib.auth
, but this time it was an API implementation so it wasn't easy.
There was a library for API django-rest-auth, so I will proceed using this. Masu
--Transition from top page to password reset screen --Email address input / send --Receive email including URL --Enter / send password
API --Receive request including email address --Send an email including the URL to the reset screen --Receive request including password
It becomes the flow of. It's a common flow
If you use django.contrib.auth
as it is, you can almost complete it just by setting the template, but this time it will be API endpoint creation, so we will use the library
According to Documentation, it seems to be a library that performs user registration, login / logout, password change and reset. It was convenient but the documentation was exquisitely unfriendly, so I implemented it while reading the source code.
For the time being
pip install django-rest-auth
API If you leave it to the library, add the following two lines to ʻurls.py` and it will work
urls.py
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^', include('django.contrib.auth.urls')),
If this is left as it is, the email template cannot be set. If you do not set the template, you could not set the domain of the URL described in the email
It seems that you need to override the django-rest-auth serializer to set it up
Specify ʻemail_template_name etc. in
get_email_options`. There seems to be other items that can be set
serializers.py
from rest_auth.serializers import PasswordResetSerializer
class CustomPasswordResetSerializer(PasswordResetSerializer):
def get_email_options(self):
data = {
'email_template_name': 'email/password_reset.html',
'subject_template_name': 'email/password_reset_subject.txt',
}
return data
The Email template has django default template, so please refer to it. please look
Please direct to the front URL with {{protocol}}: // {{domain}}
django/django/contrib/admin/templates/registration/password_reset_email.html
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}
And adjust views.py
accordingly
I referred to here
views.py
from rest_framework.generics import GenericAPIView
from user.serializers import CustomPasswordResetSerializer
class PasswordResetView(GenericAPIView):
permission_classes = (permissions.AllowAny,)
serializer_class = CustomPasswordResetSerializer
def post(self, request):
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response('Password reset e-mail has been sent.', status=200)
return Response(serializer.errors, status=400)
Finally, route this view with ʻurls.py` (1st line)
urls.py
url(r'^/password/reset/$', PasswordResetView.as_view()),
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^', include('django.contrib.auth.urls')),
You now have two APIs
--/ password / reset /
: For sending email address
--/ rest-auth / password / reset / confirm /
: For password transmission
I think it's okay to leave it to django-rest-auth
for password transmission
It seems that there are two things to prepare on the front side (please also prepare the transition source and destination etc.) The contents to be registered in the view and the API are as follows
Create a form to enter your email address
/password/reset/
Create two forms to enter the password, including confirmation
/rest-auth/password/reset/confirm/
uid and token specify the character string included in the URL included in the email.
https://***/reset/{ uid }/{ token }/
I think it's a pretty aggressive method I'm wondering if there is a better way
Recommended Posts