This python package provides a simple password reset strategy for django rest framework, where users can request password reset tokens via their registered e-mail address.
The main idea behind this package is to not make any assumptions about how the token is delivered to the end-user (e-mail, text-message, etc...). Instead, this package provides a signal that can be reacted on (e.g., by sending an e-mail or a text message).
This package basically provides two REST endpoints:
- Request a token
- Verify (confirm) a token (and change the password)
- Install the package from pypi using pip:
pip install django-rest-passwordreset
- Add
django_rest_passwordreset
to yourINSTALLED_APPS
(afterrest_framework
) within your Django settings file:
INSTALLED_APPS = (
...
'django.contrib.auth',
...
'rest_framework',
...
'django_rest_passwordreset',
...
)
- This package provides two endpoints, which can be included by including
django_rest_passwordreset.urls
in yoururls.py
as follows:
from django.conf.urls import url, include
urlpatterns = [
...
url(r'^api/password_reset/', include('django_rest_passwordreset.urls', namespace='password_reset')),
...
]
Note: You can adapt the url to your needs.
The following endpoints are provided:
POST ${API_URL}/reset_password/
- request a reset password token by using theemail
parameterPOST ${API_URL}/reset_password/confirm/
- using a validtoken
, the users password is set to the providedpassword
where ${API_URL}/
is the url specified in your urls.py (e.g., api/password_reset/
)
The following settings can be set in Djangos settings.py
file:
-
DJANGO_REST_MULTITOKENAUTH_RESET_TOKEN_EXPIRY_TIME
- time in hours about how long the token is active (Default: 24)Please note: expired tokens are automatically cleared based on this setting in every call of
ResetPasswordRequestToken.post
.
reset_password_token_created(reset_password_token)
Fired when a reset password token is generatedpre_password_reset(user)
- fired just before a password is being resetpost_password_reset(user)
- fired after a password has been reset
-
Create two new django templates:
email/user_reset_password.html
andemail/user_reset_password.txt
. Those templates will contain the e-mail message sent to the user, aswell as the password reset link (or token). Within the templates, you can access the following context variables:current_user
,username
,email
,reset_password_url
. Feel free to adapt this to your needs. -
Add the following code, which contains a Django Signal, to your application (see this part of the django documentation for more information on where to put signals).
from django.dispatch import receiver
from django_rest_passwordreset.signals import reset_password_token_created
from django.urls import reverse
@receiver(reset_password_token_created)
def password_reset_token_created(sender, reset_password_token, *args, **kwargs):
"""
Handles password reset tokens
When a token is created, an e-mail needs to be sent to the user
:param sender:
:param reset_password_token:
:param args:
:param kwargs:
:return:
"""
# send an e-mail to the user
context = {
'current_user': reset_password_token.user,
'username': reset_password_token.user.username,
'email': reset_password_token.user.email,
'reset_password_url': "{}?token={}".format(reverse('password_reset:reset-password-request'), reset_password_token.key)
}
# render email text
email_html_message = render_to_string('email/user_reset_password.html', context)
email_plaintext_message = render_to_string('email/user_reset_password.txt', context)
msg = EmailMultiAlternatives(
# title:
_("Password Reset for {title}".format(title="Some website title")),
# message:
email_plaintext_message,
# from:
"[email protected]",
# to:
[reset_password_token.user.email]
)
msg.attach_alternative(email_html_message, "text/html")
msg.send()
- You should now be able to use the endpoints to request a password reset token via your e-mail address. If you want to test this locally, I recommend using some kind of fake mailserver (such as maildump).
Django 2.1 introduced a breaking change for migrations (see Django Issue #29790). We therefore had to rewrite the migration 0002_pk_migration.py such that it covers Django versions before (<
) 2.1 and later (>=
) 2.1.
Some information is written down in Issue #8.
This library tries to follow the unix philosophy of "do one thing and do it well" (which is providing a basic password reset endpoint for Django Rest Framework). Contributions are welcome in the form of pull requests and issues! If you create a pull request, please make sure that you are not introducing breaking changes.
See folder tests/. Basically, all endpoints are covered with multiple unit tests.
Use this code snippet to run tests:
pip install -r requirements_test.txt
python setup.py install
cd tests
python manage.py test