I am using the standard Django view, password_reset_confirm (), for user password reset. After the user executes the reset password in the letter, he enters a new password, and then looks at its redirection to the root of the site:
urls.py
url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', 'django.contrib.auth.views.password_reset_confirm', { 'template_name': 'website/auth/password_reset_confirm.html', 'post_reset_redirect': '/', }, name='password_reset_confirm'),
After being redirected by a Django user, he is not authenticated. I do not want him to enter the password again, instead I want to verify its authenticity after he set the new password.
To implement this feature, I created a delegate view. It wraps the standard and processes its output. Since standard browsing redirects the user only if the reset password succeeds, I check the status code of the response that it returns, and if it redirects, retrieves the user from the database again and confirms it.
urls.py
url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', views.password_reset_confirm_delegate, { 'template_name': 'website/auth/password_reset_confirm.html', 'post_reset_redirect': '/', }, name='password_reset_confirm'),
views.py
@sensitive_post_parameters() @never_cache def password_reset_confirm_delegate(request, **kwargs): response = password_reset_confirm(request, **kwargs)
backends.py
class PasswordlessAuthBackend(ModelBackend): """Log in to Django without providing a password. """ def authenticate(self, username, passwordless=False): if not passwordless: return None try: return User.objects.get(username=username) except User.DoesNotExist: return None def get_user(self, user_id): try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None
settings.py
AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', 'website.backends.PasswordlessAuthBackend' )
Are there any better ways to do this?