[PYTHON] How to reset password via API using Django rest framework

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

Password reset flow

User

--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

What is django-rest-auth?

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

Implementation in 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

front

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

View to enter email address

Create a form to enter your email address

/password/reset/

View to enter password

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 }/

Summary

I think it's a pretty aggressive method I'm wondering if there is a better way

Recommended Posts

How to reset password via API using Django rest framework
How to create a Rest Api in Django
How to automatically generate API document with Django REST framework & POST from document screen
How to write custom validations in the Django REST Framework
Implementation of CRUD using REST API with Python + Django Rest framework + igGrid
Create a REST API to operate dynamodb with the Django REST Framework
How to deal with garbled characters in json of Django REST Framework
How to build an application from the cloud using the Django web framework
How to display Map using Google Map API (Android)
How to get article data using Qiita API
Django REST framework A little useful to know.
How to get people to try out django rest framework features in one file
Django REST framework basics
Django Rest Framework Tips
[Rails] How to get location information using Geolocation API
RHCSA exam preparation --how to reset root account password
When you want to filter with Django REST framework
Implement APIs at explosive speed using Django REST Framework
[Django Rest Framework] Customize the filter function using Django-Filter
How to analyze with Google Colaboratory using Kaggle API
Kintone REST API snippet (How to write API token authentication header, how to write login name password authentication header, how to write query)
Creating an API that returns negative-positive inference results using BERT in the Django REST framework
The first API to make with python Djnago REST framework
How to resolve CSRF Protection when using AngularJS with Django
How to generate a query using the IN operator in Django
Django REST framework stumbling block
Django REST framework with Vue.js
Login with django rest framework
Implementation of JWT authentication functionality in Django REST Framework using djoser
How to get followers and followers from python using the Mastodon API
[Django] How to test Form [TDD]
How to reflect CSS in Django
How to get started with Django
How to use OpenPose's Python API
Install Python framework django using pip
How to use bing search api
How to write Django1.9 environment-independent wsgi.py
[Django] Use MessagePack with Django REST framework
[Python] How to use Typetalk API
How to authenticate with Django Part 2
How to authenticate with Django Part 3
Try using the Python web framework Django (1)-From installation to server startup
Development and deployment of REST API in Python using Falcon Web Framework
How to get a sample report from a hash value using VirusTotal's API
[Rails] How to detect radical images by analyzing images using Cloud Vision API
I want to create an API that returns a model with a recursive relationship in the Django REST Framework
How to do arithmetic with Django template
Create RESTful APIs with Django Rest Framework
Logical deletion in Django, DRF (Django REST Framework)
Understand the benefits of the Django Rest Framework
ng-admin + Django REST framework ready-to-create administration tool
How to check the version of Django
How to draw a graph using Matplotlib
Bulk posting to Qiita: Team using Qiita API
How to set up SVM using Optuna
How to delete expired sessions in Django
CRUD GET with Nuxt & Django REST Framework ②
Miscellaneous notes about the Django REST framework
CRUD POST with Nuxt & Django REST Framework
How to install a package using a repository
How to set xg boost using Optuna