Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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 ?

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

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')
like image 955
TJB Avatar asked Oct 18 '22 03:10

TJB


1 Answers

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. If you have a custom password change view and wish to have similar behavior, use the update_session_auth_hash() function.

like image 53
Kevin Christopher Henry Avatar answered Oct 27 '22 11:10

Kevin Christopher Henry