Django request.user always returns AnonymousUser despite a token being sent with the request

i have a class that beehives differently depending on if the user is authenticated or not:

class SomeClass(APIView):
    authentication_classes = ()
    permission_classes = ()

    def get(self, request):
        if request.user.is_authenticated:
            # do something...
        else:
            # do something else...

it used to work perfectly with django 3.2.5 and JSONWebTokenAuthentication. however i had to upgrade to django 4.x and TokenAuthentication... with:

authentication_classes = (TokenAuthentication, )

the user is available but the request returns 401 to anonymous users... with:

authentication_classes = ()

anonymous requests are accepted, but i can't see the data of authenticated users.

You need to log in and save the user in the session

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth import authenticate, login

class LoginView(APIView):
    # authentication_classes = ()
    permission_classes = ()
    def post(self, request):
        email = request.data.get("email")
        password = request.data.get("password")
        user = authenticate(email=email, password=password) # TODO Check if use can be authenticated
        
        if user:
            login(request, user) #TODO use login to store session of the logged in user
            return Response({
                "userId":user.id,
                "firstname": user.first_name,
                "lastname": user.last_name,
                "email": user.email,
                "token": user.auth_token.key,
                "other_fiels": "other"
            })
        else:
            return Response({"error": (email, password)}, status=status.HTTP_400_BAD_REQUEST)

ok. i finally ended up extending the TokenAuthentication class:

from rest_framework.authentication import TokenAuthentication

class MyTokenAuthentication(TokenAuthentication):

    def authenticate_credentials(self, key):
        model = self.get_model()
        try:
            token = model.objects.select_related('user').get(key=key)
        except model.DoesNotExist:
            # raise exceptions.AuthenticationFailed(_('Invalid token.'))
            return None

        if not token.user.is_active:
            # raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
            return None
        return token.user, token

instead of raising an exception i return None. this way the request object within a function contains the user data if the user is authenticated otherwise anonymous.

Back to Top