简体   繁体   English

Django request.user在重定向后变为匿名

[英]Django request.user becomes anonymous after redirect

In my Django app I create a User from django.contrib.auth.models, and I am using request.user in multiple view functions without a problem. 在我的Django应用程序中,我从django.contrib.auth.models创建了一个用户,我在多个视图函数中使用request.user没有问题。 In one of my view functions I change the user password, save the user, and redirect the client to another view function. 在我的一个视图功能中,我更改用户密码,保存用户,并将客户端重定向到另一个视图功能。 Once I try to get the user from the request in that function, the user is Anonymous. 一旦我尝试从该功能中的请求中获取用户,该用户就是匿名用户。 After using User.set_password() or redirecting, does it take the user out of the session ? 使用User.set_password()或重定向后,是否会使用户退出会话?

views.py views.py

from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from .models import Profile
from .forms import ProfileForm, PasswordForm


def sign_in(request):
    form = AuthenticationForm()
    if request.method == 'POST':
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            if form.user_cache is not None:
                user = form.user_cache
                if user.is_active:
                    login(request, user)
                    return HttpResponseRedirect(
                        reverse('home')  # TODO: go to profile
                    )
                else:
                    messages.error(
                        request,
                        "That user account has been disabled."
                    )
            else:
                messages.error(
                    request,
                    "Username or password is incorrect."
                )
    return render(request, 'accounts/sign_in.html', {'form': form})


def sign_up(request):
    form = UserCreationForm()
    if request.method == 'POST':
        form = UserCreationForm(data=request.POST)
        if form.is_valid():
            form.save()
            user = authenticate(
                username=form.cleaned_data['username'],
                password=form.cleaned_data['password1']
            )
            new_profile = Profile.objects.create(user=user)
            login(request, user)
            messages.success(
                request,
                "You're now a user! You've been signed in, too."
            )
            return HttpResponseRedirect(reverse('home'))  # TODO: go to profile
    return render(request, 'accounts/sign_up.html', {'form': form})


def sign_out(request):
    logout(request)
    messages.success(request, "You've been signed out. Come back soon!")
    return HttpResponseRedirect(reverse('home'))

def profile(request):
    user = request.user
    try:
        account = Profile.objects.get(user=user)
    except Profile.DoesNotExist:
        account = None

    print(account.first_name)
    context = {'account': account}

    return render(request, 'accounts/profile.html', context)

def edit(request):
    account = Profile.objects.get(user=request.user)
    form = ProfileForm(instance=account)

    if request.method == 'POST':
        account = Profile.objects.get(user=request.user)

        form = ProfileForm(request.POST, request.FILES)

        if form.is_valid():
            account.first_name = form.cleaned_data['first_name']
            account.last_name = form.cleaned_data['last_name']
            account.email = form.cleaned_data['email']
            account.bio = form.cleaned_data['bio']
            account.avatar = form.cleaned_data['avatar']
            account.year_of_birth = form.cleaned_data['year_of_birth']
            account.save()

            context = {'account': account}

            return HttpResponseRedirect('/accounts/profile')
        else:
            x =form.errors
            context = {'form': form, 'errors': form.errors}

            return render(request, 'accounts/edit.html', context)

    else:

        context = {'form': form}

    return render(request, 'accounts/edit.html', context)

def change_password(request):
    user = request.user

    if request.method == 'POST':
        form = PasswordForm(request.POST)

        if form.is_valid():
            cleaned_data = form.cleaned_data

            if not user.check_password(cleaned_data['old_password']):
                form.add_error('old_password', 'Old password is incorrect')

                context = {'form': form}

                return render(request, 'accounts/password.html', context)

            try:
                user.set_password(cleaned_data['new_password'])
                user.save()

                return HttpResponseRedirect('/accounts/profile')
            except Exception as e:
                form = PasswordForm()

                context = {'form': form}

                return render(request, 'accounts/password.html', context)

    else:
        form = PasswordForm()

        context = {'form': form}

        return render(request, 'accounts/password.html', context)

forms.py forms.py

class PasswordForm(forms.Form):
    old_password = forms.CharField(max_length=200)
    new_password = forms.CharField(max_length=200)
    confirm_password = forms.CharField(max_length=200)

    def clean(self, *args, **kwargs):
        cleaned_data = super(PasswordForm, self).clean()

        if 'new_password' in cleaned_data:
            new_password = cleaned_data['new_password']
        else:
            new_password = None

        if 'confirm_password' in cleaned_data:
            confirm_password = cleaned_data['confirm_password']
        else:
            confirm_password = None

        if confirm_password and new_password:
            if new_password != confirm_password:
                self.add_error('confirm_password', 'Passwords do not match')

Yes. 是。 See the documentation about session invalidation on password change . 请参阅有关密码更改的会话失效的文档。 To fix it, see this bit in particular: 要修复它,请特别注意这一点:

The default password change views included with Django, PasswordChangeView and the user_change_password view in the django.contrib.auth admin, update the session with the new password hash so that a user changing their own password won't log themselves out. Django, PasswordChangeViewdjango.contrib.auth管理员中的user_change_password视图中包含的默认密码更改视图使用新密码哈希更新会话,以便更改自己密码的用户不会自行注销。 If you have a custom password change view and wish to have similar behavior, use the update_session_auth_hash() function. 如果您有自定义密码更改视图并希望具有类似行为,请使用update_session_auth_hash()函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM