Got an AnonymousUser using DRF

I don’t understand why the user gets lost after logging in using the login/ URL. If after login you go to the profile/ URL, you get an error stating that the user is anonymous, AnonymousUser.

urls.py:

from django.urls import path
from .views import ProfileView, LoginView


urlpatterns = [
    path('profile/', ProfileView.as_view(), name='profile'),
    path('login/', LoginView.as_view(), name='login'),
]

settings.py:

ALLOWED_HOSTS = ['*']

CORS_ALLOWED_ORIGINS = [
    'http://localhost:3000',
    'http://127.0.0.1:3000',
]

CORS_ALLOW_CREDENTIALS = True

CSRF_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_HTTPONLY = False 
SESSION_COOKIE_HTTPONLY = True

SESSION_COOKIE_SECURE = False

CSRF_TRUSTED_ORIGINS = ['http://localhost:3000', 'http://127.0.0.1:3000']

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'core.apps.CoreConfig',
    'userprofile.apps.UserprofileConfig',
    'rest_framework',
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],
}

serializer.py:

class LoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

class UserProfileSerializer(serializers.ModelSerializer):
    username = serializers.CharField(source='user.username')
    user_image = serializers.ImageField(max_length=None, use_url=True, allow_null=True, required=False)

    class Meta:
        model = UserProfile
        fields = ['username', 'user_header', 'user_image']

    def update(self, instance, validated_data):
        instance.user.username = validated_data.get('username', instance.user.username)
        instance.user_header = validated_data.get('user_header', instance.user_header)

        user_image_data = validated_data.get('user_image')
        if user_image_data:
            format, imgstr = user_image_data.split(';base64,')
            ext = format.split('/')[-1]
            id = uuid.uuid4()
            data = ContentFile(base64.b64decode(imgstr), name=id.urn[9:]+'.'+ext)
            instance.user_image.save(f'{id}.{ext}', data, save=False)

        instance.user.save()
        instance.save()
        return instance

views.py:

class LoginView(APIView):
    def post(self, request):
        serializer = LoginSerializer(data=request.data)
        if serializer.is_valid():
            username = serializer.validated_data.get('username')
            password = serializer.validated_data.get('password')
            user = authenticate(request, username=username, password=password)
            if user is not None:
                login(request, user)
                print(request.session.session_key)
                return Response({'detail': 'Успешный вход в систему'}, status=status.HTTP_200_OK)
        return Response({'error': 'Неверное имя пользователя или пароль'}, status=status.HTTP_400_BAD_REQUEST)
 

class ProfileView(APIView):
    def get(self, request):
        profile = UserProfile.objects.get(user=request.user)
        serializer = UserProfileSerializer(profile)
        return Response(serializer.data)
    
    def put(self, request):
        profile = UserProfile.objects.get(user=request.user)
        serializer = UserProfileSerializer(profile, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'detail': 'Успешный вход в систему'}, status=status.HTTP_200_OK)
        return Response({'error': 'Неверное имя пользователя или пароль'}, status=status.HTTP_400_BAD_REQUEST)

models.py:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='userprofile', on_delete=models.CASCADE)
    user_image = models.ImageField(upload_to=f'images/userphoto/', blank=True, null=True)
    user_header = models.CharField(max_length=255, blank=True, null=True)

    def __str__(self):
        return self.user.username


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)


@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.userprofile.save()


@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)
    else:
        instance.userprofile.save()

Side note: When requesting assistance with an error, it’s usually a lot more helpful to post the complete error with the traceback from the server console than providing a screenshot from the browser.

I’m assuming your print statement for the session_key shows a valid session being returned. The next thing I’d check then would be to ensure that the response contains the cookie, that it has been sent to the browser, and that the browser is returning it on the subsequent request.

Also, the way you have your models defined, there’s no requirement or expectation that a Profile model is going to have the same PK as its related User model. You can’t guarantee that you’re going to get the right profile by your query. You should reference the Profile object directly as request.user.userprofile.

1 Like

thanks a lot for help, ive changed this UserProfile.objects.get(user=request.user) into this request.user.userprofile and that worked for me