Пользователь django вышел из системы после смены пароля

У меня проблема с пользователями Django, которые меняют пароли. Я создал несколько рабочих сайтов в Django, всего лишь один год (или в версии 1.8), но я не помню, чтобы эта проблема была раньше.

Резюме

Когда пользователь меняет свой пароль, пользователь выходит из системы, но пароль успешно изменен.

Подробнее

У меня есть представление, которое позволяет пользователю сменить пароль, я использую стандартные формы django и структуру auth, а подчеркнуть: смена пароля работает, он просто регистрирует пользователя, чтобы он снова войдите в систему.

На самом деле я не против этого ужасно, я бы предпочел, чтобы пользователь был перенаправлен на свою панель управления с обновлением сообщения, если мне нужно перезапустить пользователя в коде, тогда я просто выгляжу вроде неуклюжим.

вот моя функция просмотра:

@login_required
def user_change_password(request):
    """Allows a user to change their password"""

    if request.method == "POST":
        form = SubscriberPasswordForm(request.POST)
        if form.is_valid():
            try:
                request.user.set_password(form.cleaned_data['password'])
                request.user.save()
            except Exception, err:
                print "Error changing password: {}".format(err)
                messages.add_message(request, messages.ERROR, 'The password could not be changed, please try again '
                                                              'later. This admins have been notified of this error.')
            else:
                #this outputs True
                print request.user.is_authenticated()

                messages.add_message(request, messages.INFO, 'Your password has been changed successfully')
                return HttpResponseRedirect("/accounts/dashboard/")
    else:
        form = SubscriberPasswordForm()

    return render(request, "accounts/change-password.html", {"form": form})

Таким образом, пароль изменен, пользователь будет перенаправлен на страницу панели мониторинга, затем обработчик @login_required затем перенаправляет их обратно на экран входа в систему.

Форма пароля здесь, хотя это довольно просто.

class SubscriberPasswordForm(forms.Form):
    password = forms.CharField(widget=forms.PasswordInput)
    cpassword = forms.CharField(widget=forms.PasswordInput)

    def clean_cpassword(self):
        password1 = self.cleaned_data.get("password")
        password2 = self.cleaned_data.get("cpassword")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'],
                code='password_mismatch',
            )

Ответ 1

Насколько я понимаю, выход из системы происходит после изменения пароля в Django 1.7. Так что вам нужно будет повторно авторизовать пользователя в вашем коде, как вы сказали.

См. Примечания к выпуску: https://docs.djangoproject.com/en/1.8/releases/1.7/#django-contrib-auth

Вот конкретное примечание: "Был добавлен метод AbstractBaseUser.get_session_auth_hash(), и если ваш AUTH_USER_MODEL наследуется от AbstractBaseUser, изменение пароля пользователя теперь делает недействительными старые сеансы, если включен SessionAuthenticationMiddleware. Для получения более подробной информации, включая замечания по обновлению, см. Сеанс недействительности при смене пароля. при включении этого нового промежуточного программного обеспечения. "

См. Документацию: https://docs.djangoproject.com/en/1.7/topics/auth/default/#session-invalidation-on-password-change.

Ответ 2

Для django 1.9:

from django.contrib.auth import update_session_auth_hash

def password_change(request):
    if request.method == 'POST':
        form = PasswordChangeForm(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            update_session_auth_hash(request, form.user)

В запросе POST должны быть указаны следующие поля:

  • old_password
  • new_password1
  • new_password2

См. подробные документы в https://docs.djangoproject.com/en/1.9/topics/auth/default/#session-invalidation-on-password-change

Ответ 3

Для Django 1.8

Просто позвоните update_session_auth_hash после set_password так:

from django.contrib.auth import update_session_auth_hash

request.user.set_password(form.cleaned_data['password'])
update_session_auth_hash(request, request.user)