Django password reset email link redirects to login page

django custom password reset email
django login session
django login source code
django password reset not sending email
django add user to group
django usercreationform
django-allauth password reset
django user model

I am using custom forms to override the Django templates but when a user clicks reset password and receives the email with the password reset link, etc (EDITED QUESTION TO CHANGE ORDER FROM reset-password to password-reset)

/reset/OA/50l-94673624f6b9fa5a060a/

When the link is clicked it redirects to

/account/login/

It should be directing them to

/password-reset/confirm/

and then to

/password-reset/complete/

The command line looks like this when reset link is clicked

GET /reset/OA/50l-94673624f6b9fa5a060a/ HTTP/1.1" 302 0
GET /account/login/ HTTP/1.1" 200 2237

LOGIN_EXEMPT_URLS

LOGIN_EXEMPT_URLS = {
    r'^account/logout/$',
    r'^account/register/$',
    r'^account/password-reset/$',
    r'^account/password-reset/done/$',
    r'^account/password-reset/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>,+)/$',
    r'^account/password-reset/complete/$',

}

urls.py

app_name='accounts'

from django.conf.urls import url
from . import views
from django.contrib.auth.views import LoginView, LogoutView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView, PasswordResetCompleteView
from django.conf import settings
from django.conf.urls.static import static
from django.urls import reverse_lazy

urlpatterns = [
    url(r'^$', views.home, name='home'),
    url(r'^login/$', LoginView.as_view(template_name='accounts/login.html'), name='login'),
    url(r'^logout/$', LogoutView.as_view(template_name='accounts/logout.html'), name='logout'),
    url(r'^register/$', views.register, name='register'),
    url(r'^profile/$', views.view_profile, name='view_profile'),
    url(r'^profile/edit$', views.edit_profile, name='edit_profile'),
    url(r'^change-password/$', views.change_password, name='change_password'),

    url(r'^password-reset/$',
    PasswordResetView.as_view(template_name='accounts/password_reset.html',
    success_url=reverse_lazy('accounts:password_reset_done')),
    {'email_template_name': 'accounts/password_reset_email.html'},
    name='password_reset'),

    url(r'^password-reset/done/$',
    PasswordResetDoneView.as_view(template_name='accounts/password_reset_done.html'),
    name='password_reset_done'),

    url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>,+)/$',
    PasswordResetConfirmView.as_view(template_name='accounts/password_reset_confirm.html'),
    name='password_reset_confirm'),

    url(r'^password-reset/complete/$',
    PasswordResetCompleteView.as_view(template_name='accounts/password_reset_complete.html'),
    name='password_reset_complete'),

]

settings.py

INSTALLED_APPS = [
    'accounts',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

middleware.py

import re

from django.conf import settings
from django.urls import reverse
from django.shortcuts import redirect
from django.contrib.auth import logout

EXEMPT_URLS = [re.compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
    EXEMPT_URLS += [re.compile(url) for url in settings.LOGIN_EXEMPT_URLS]

class LoginRequiredMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        assert hasattr(request, 'user')
        path = request.path_info.lstrip('/')
        url_is_exempt = any(url.match(path) for url in EXEMPT_URLS)

        if path == reverse('accounts:logout').lstrip('/'):
            logout(request)

        if request.user.is_authenticated and url_is_exempt:
            return redirect(settings.LOGIN_REDIRECT_URL)
        elif request.user.is_authenticated or url_is_exempt:
            return None

        else:
            return redirect(settings.LOGIN_URL)

password_reset_email.html

{% load i18n %}{% autoescape off %}
{% blocktrans %} You're recieving 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 "Thank you for using x!" %}

{% blocktrans %}The {{ site_name }} team{% endblocktrans %}

{% endautoescape %}

You should change from PasswordResetConfirmView to PasswordResetCompleteView.

PasswordResetCompleteView presents a view which informs the user that password has been successfully changed. You don't need to write PasswordResetConfirmView twice.

Change to

url(r'^reset-password/complete/$',
PasswordResetCompleteView.as_view(template_name='accounts/reset_password_complete.html'),
name='reset_password_complete'),

For more detail, check django docs. (https://docs.djangoproject.com/en/2.1/topics/auth/default/#django.contrib.auth.views.PasswordResetCompleteView)

Try to change password at /accounts/password/change. We'll occasionally send you account related emails. is set for PasswordChangeView , it will return the URL to login, but with a redirect back to password change. I got this working with django-allauth by overriding the form_valid method of the  What we want is a password_reset page where the user can enter their email address, and be sent a cryptographically secure email with a one-time link to a reset page. Fortunately Django has us covered. If you recall the complete set of views and URLs provided by the Django auth app, there are already several for resetting a password.

change in the settings seption the confirm part to just account/password-rest/confirm/ without dollar sign so everything after that url will be exempt aswell.

LOGIN_EXEMPT_URLS = {
  r'^account/logout/$',
  r'^account/register/$',
  r'^account/password-reset/$',
  r'^account/password-reset/done/$',
  r'^account/password-reset/confirm/',
  r'^account/password-reset/complete/$',
}

Implement user authentication with a password reset for Django 3.0 work where we added Login & Logout pages and then a Signup page. and be sent a cryptographically secure email with a one-time link to a reset page. file by adding the following two lines at the bottom under our redirect URLs. Django Change Password & Reset Forgot Password Using Built-in Functions. 7th July 2019 Huzaif Sayyed. In this short tutorial, I will explain how to use Change Password and Reset or Forgot Password Functionality in Django. The process for Password Reset involves sending emails. For that matter, we are going to use console email backend and check

You have included your password reset URLs in a urls.py which has app_name = 'accounts', therefore you need to include the accounts namespace when reversing the URLs.

{% url 'accounts:password_reset_confirm' uidb64=uid token=token %}

As an aside, I've seen several questions on Stack Overflow where namespacing the password reset URLs caused problems. In my opinion, it's simpler to include the password reset URLs in a urls.py that does not use a namespace.

The log line GET /reset/OA/50l-94673624f6b9fa5a060a/ suggests that you have included the password reset URLs in a second place. I would try to track down this extra include and remove it.

It prompts you to change the password of a given user which you must enter twice. the user has an email in the desired domain and if not, redirects to the login page: Returns the URL that users who don't pass the test will be redirected to. There when you input the right credentials, it redirects you to the same page you wanted to access before the log-in page. This kind of redirection not only limits to the Django Admin but there are more operations like, when adding new objects in models via admin, changing passwords and many more. Page Redirection is an important factor in

In djangobin app's views.py file , add login , logout and user_details views from django.core.mail import mail_admins correct username and password login the user <a href="/password-reset/">Forgot Password? and password and you will be redirected to user detail page:. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more Django authentication - wrong redirect url to login page. Ask Question Asked 9 years, 5 months ago. Active 9 years, 5 months ago. View

#Add Django site authentication urls (for login, logout, password management) urlpatterns Redirect to home URL after login (Default redirects to The default password reset system uses email to send the user a reset link. Now if you revisit the homepage and login you'll be redirected to the new hompage that has a "logout" link for logged in users. Clicking it takes you back to the homepage with a "login" link. Conclusion. With very little code we have a robust login and logout authentication system.

How to use Django Built-in Password Reset and Change Password Functionality. How to is also a way to redirect a user after changing the password successfully. ( Django custom password reset email, Django override password reset form). h3> <a href="{% url 'login' %}">Click here to Login</a>  Using the Django authentication system¶. This document explains the usage of Django’s authentication system in its default configuration. This configuration has evolved to serve the most common project needs, handling a reasonably wide range of tasks, and has a careful implementation of passwords and permissions.

Comments
  • user.is_authenticated will always return False if the user is logged out as it becomes AnonymousUser.is_authenticated . And why would a logged in user reset his password. And I guess for that reason your process_view always does return redirect(settings.LOGIN_URL)
  • You need to make sure that your password reset URLs are included in LOGIN_EXEMPT_URLS. It might be useful for you to show your email template - the URL in your question /reset/OA/50l-94673624f6b9fa5a060a/ does not seem to match your URL pattern r'^reset-password/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>,+)/$',.
  • Note that final view should use PasswordResetCompleteView. You have PasswordResetConfirmView twice. I suggest you use the same names as Django does, e.g. password_reset_complete. Switching the order to reset_password_complete makes it confusing to other Django users.
  • @VineethSai Thank you, how would I go about changing that so that only a logged out user has the ability to reset password?
  • @VineethSai I'm using 2.1.2 and when I change it to request.user.is_authenticated() it throws an error 'bool' object is not callable
  • Thanks, I totally didn't realise I mistyped ConfirmView twice!
  • The email link still redirects to account/login/
  • Hi Alasdair, thanks for the help I really appreciate it. I did have the namespace in the email template as {% url 'accounts:password_reset_confirm' uidb64=uid token=token %} however it threw this error NoReverseMatch at /account/password-reset/ Reverse for 'password_reset_confirm' with keyword arguments '{'uidb64': 'NA', 'token': '50l-b062bef8209ab6b2b65d'}' not found. 1 pattern(s) tried: ['account/password-reset/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>,+)/$'] and when I took out the namespace it went to password_reset_done page where it says We've emailed you instructions etc
  • How would you go about tracking down the extra include? I can't seem to find it.
  • (?P<token>,+) looks like a mistake. Look at the regex used in Django 1.11, or since you are using Django 2.0, consider switching to path.
  • To find the extra include, you just need to search your urls.py files for password_reset_confirm. You may have include('django.contrib.auth.urls') somewhere.
  • Okay, thank you, I've now switched everything over to path so am using reset/<uidb64>/<token>/ but the reset password link still redirects to the login page? And there is no other instance of password_reset_confirm