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.