Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

700
Views
django.contrib.auth.login() function not returning any user as logged in

I have created a basic app using Django's built in authentication system. I successfully created a User object in the shell using >>python manage.py createsuperuser.

I then created a basic view, 'UserLogin' along with corresponding serializers/urls, to log an existing user in using the django.contrib.auth authenticate(), and login() functions. Upon testing with the credentials of my created user, the login function seemed to have worked successfully.

To test this, I created another view function, 'CurrentUser' which returns the username of the currently logged in user. However, this view returns the user as empty.

Why would the 'CurrentUser' view be returning no user as logged in? I have attached my code (minus imports) below.

views.py:

class UserLogin(APIView):
    def post(self, request, format = None):
        serializer = UserLoginSerializer(data=request.data)
        if serializer.is_valid():
            user = authenticate(username=serializer.validated_data["username"], password=serializer.validated_data["password"])
            if user is not None:
                login(request, user)
                return Response(UserSerializer(user).data, status=status.HTTP_201_CREATED)
            return Response("Invalid username/password", status=status.HTTP_401_UNAUTHORIZED)
        return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)

class CurrentUser(APIView):
    def get(self, request, format = None):
        return Response(self.request.user.username)

serializers.py:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username']

class UserLoginSerializer(serializers.Serializer):
    username = serializers.CharField(max_length=300, required=True)
    password = serializers.CharField(required=True, write_only=True)

urls.py:

urlpatterns = [
    path('login/', views.UserLogin.as_view()),
    path('current/', views.CurrentUser.as_view())
]

Any guidance would be much appreciated.

Thanks

over 4 years ago · Santiago Trujillo
6 answers
Answer question

0

A cause for this could be a missing SessionMiddleware:

  1. Your /login view works
  2. It persists stuff in the session but the middleware isn't installed
  3. The next request to /current isn't bound to the authenticated session

Can you double check that settings.MIDDLEWARES contain django.contrib.sessions.middleware.SessionMiddleware?

over 4 years ago · Santiago Trujillo Report

0

You were trying to test the authentication in the wrong way. This is API, which is stateless. That is Django doesn't have any idea about the previous request that you have made to the UserLogin.

So, you need to attach the token and session-id (or something that can be used to identify the user) with the "second request".

Since you are using DRF, you don't have to write your own authentication mechanisms. You can use DRF's BasicAuthentication (or any other authentication scheme) to authenticate.

So, change your view as

from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated


class CurrentUser(APIView):
    authentication_classes = (BasicAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        return Response({
            "user": {
                "id": request.user.id,
                "username": request.user.username
            }})

Execution using requests

In [5]: import requests                                                                                                                                                                                            

In [6]: from requests import auth                                                                                                                                                                                  

In [7]: response = requests.get(url=url, auth=auth.HTTPBasicAuth("admin", "passme123@#$"))                                                                                                                         

In [8]: print(response.json())                                                                                                                                                                                     
{'user': {'id': 1, 'username': 'admin'}}

Since you are using DRF, you can make use of any of these DRF authentications schemes in your code-base

over 4 years ago · Santiago Trujillo Report

0

You have to set the default auth class as session authenticate class in DRF settings. Read more about it here [1].

Session auth uses session id to identify the user. So you have to send the cookie based session id in the request. Read about session auth here [2].

for example:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication', # <-- set this class
    ]
}

Use this code:

def post(self, request, format = None):
    serializer = UserLoginSerializer(data=request.data)
    if serializer.is_valid():
        user = authenticate(username=serializer.validated_data["username"], password=serializer.validated_data["password"])
        if user:
            return Response(UserSerializer(user).data, status=status.HTTP_201_CREATED)
        return Response("Invalid username/password", status=status.HTTP_401_UNAUTHORIZED)
    return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED)

But my recommendation is to use Token auth [3].

To use token auth 2 things will change:

  1. The default auth class in DRF settings
  2. When sending a request to any DRF API view you to send the Auth header as Token <token-value>

Your post method and API views code will remain same.

[1] https://www.django-rest-framework.org/api-guide/authentication/#setting-the-authentication-scheme

[2] https://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication

[3] https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication

over 4 years ago · Santiago Trujillo Report

0

Since you are using Django rest framework, i m assuming you are developing rest apis. Rest Apis by design are meant to be stateless meaning no two requests will be dependent on each other.

What this essentially means is you have to authenticate every request and set the user in request after authentication.

There are many ways of doing it like many have suggested to use basicAuth, or token based authentication. All of which can we easily implemented by reading documentation Auth Doc

The out of the box django views uses cookies to identify logged in user. Which in this case is not helpful.

over 4 years ago · Santiago Trujillo Report

0

I am using DRF for login. You can check this serializers and login view.

serializers.py:

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

    def validate(self, data):
         user = authenticate(**data)
         if user and user.is_active:
               return user
    raise serializers.ValidationError("Incorrect Credentials")

login view:

    class LoginAPIView(generics.GenericAPIView):
          queryset = User.objects.all()
          permission_classes = [AllowAny]
          serializer_class = LoginSerializer

 def post(self, request, *args, **kwargs):
     serializer = self.get_serializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     user = serializer.validated_data
     return Response({
        "user": UserSerializer(user, context=self.get_serializer_context()).data,
        "token": AuthToken.objects.create(user)[1]
    }) 

settings.py rest framework classes :

REST_FRAMEWORK = {

    'DEFAULT_AUTHENTICATION_CLASSES': [
    # 'rest_framework.authentication.BasicAuthentication',
    # 'rest_framework.authentication.SessionAuthentication',
    'knox.auth.TokenAuthentication',
],
    
'DEFAULT_PERMISSION_CLASSES': [
    'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
],

'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']

}

over 4 years ago · Santiago Trujillo Report

0

You have to attach an authentication token and session-id for your purpose. I wish this document would helpful for you. I recommend you to use Token Auth2. https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!