【问题标题】:django user logged out after password changedjango用户在密码更改后注销
【发布时间】:2015-08-29 13:39:22
【问题描述】:

我在 Django 用户更改密码时遇到了问题 - 我在 Django 中建立了一些生产站点,但在大约一年内(或 1.8 中)都没有,但我不记得以前遇到过这个问题。

总结

当用户更改密码时,用户退出,但密码更改成功。

详情

我有一个允许用户更改密码的视图,我使用标准 django 表单和身份验证框架,强调:更改密码有效,它只是将用户注销,以便他们必须重新登录

我实际上并不介意这一点,我希望用户通过消息更新被重定向到他们的仪表板,如果我需要在代码中重新验证用户,那么我会这样做,只是看起来有点笨拙。

这是我的视图函数:

@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.7 中默认启用

标签: python django


【解决方案1】:

对于 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 请求中提供以下字段:

  • 旧密码
  • new_password1
  • new_password2

update_session_auth_hash查看详细文档

【讨论】:

    【解决方案2】:

    对于 Django 3、Django 1.8+ 使用此链接: https://docs.djangoproject.com/en/3.2/topics/auth/default/#django.contrib.auth.update_session_auth_hash

    或使用此代码:

    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)
        else:
            ...
    

    【讨论】:

      【解决方案3】:

      我的理解是在 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

      【讨论】:

      • 好的,谢谢 - 没看到。我认为 1.6 实际上是我使用的最后一个版本。
      【解决方案4】:

      对于 Django 1.8

      只需在set_password 之后调用update_session_auth_hash,如下所示:

      from django.contrib.auth import update_session_auth_hash
      
      request.user.set_password(form.cleaned_data['password'])
      update_session_auth_hash(request, request.user)
      

      【讨论】:

        猜你喜欢
        • 2021-01-28
        • 1970-01-01
        • 1970-01-01
        • 2019-02-07
        • 2016-05-17
        • 1970-01-01
        • 2021-12-03
        • 2021-06-19
        • 1970-01-01
        相关资源
        最近更新 更多