0

Description:

I use Django's authentication system to login a user.

When I login a user like this:

views.py:

from django.contrib.auth import authenticate, login

class Login(APIView):
    def post(self, request):
        username = request.data.get("username")
        password = request.data.get("password")

        user = authenticate(username=username, password=password)
        if user is None:
            return Response()
        else:
            login(request, user)
            #outputs True
            print(request.user.is_authenticated)
            #outputs True
            print("is_active: ", request.user.is_active)
            return Response()

I can't verify the user in a different view, e.g:

views.py

class Files(APIView):
    def get(self, request): 
        #outputs False
        print("is_authenticated", request.user.is_authenticated)
        return Response()

In my settings.py I've included:

INSTALLED_APPS = [
    ...
    'django.contrib.auth',
    'django.contrib.contenttypes',
    ...
]

MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    ...
]

Possible Problems:

  • The problem may occur because I use the django restframework
  • It may be caused because I make to independend requests to each view

Any ideas?

Philip F.
  • 1,167
  • 1
  • 18
  • 33
  • 1
    Isn't this the same as your previous question: https://stackoverflow.com/questions/67647389/django-session-not-available-on-different-view ? (You could have simply edited that question instead of posting a new one) As you yourself note in your possbile problems "It may be caused because I make to independend requests to each view", then why are you not investigating that problem? You Django code does not appear to be problematic, you need to solve this client side. – Abdul Aziz Barkat May 23 '21 at 10:51
  • @AbdulAzizBarkat I rewrote the code with the django authorization framework. From the [django docs](https://docs.djangoproject.com/en/3.2/topics/auth/default/) for user authorization, it looks like the solution provided is server-sided only. I've posted a new question since I use an approach here, which strongly differs from the previous one. But I guess I'm gonna close the previous question. – Philip F. May 23 '21 at 12:14

1 Answers1

2

As far as I know, when using rest_framework.views.APIView you must specify the authentication_classes to use. For that you have two solutions :

1. Configuration-style method

Set authentication methods in your settings.py file :

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
     ),
     'DEFAULT_PERMISSIONS_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
        'rest_framework.permissions.IsAdminUser',
     ),
}

Solution might duplicate : Allauth request.user is AnonymousUser in APIView, but is_authenticated in View

2. In-class method

Set the authentication_classes class attribute :

from rest_framework.views import APIView
from rest_framework import authentication, permissions

class Files(APIView):

    authentication_classes = [authentication.BasicAuthentication, authentication.SessionAuthentication] # Choose your prefered method
    permission_classes = [permissions.IsAuthenticated, permissions.IsAdminUser]                         # If you wish to use permissions

    def get(self, request): 
        # Should be an instance of django.contrib.auth.User
        print("user", request.user)
        # Should be True
        print("is_authenticated", request.user.is_authenticated)
        return Response()

More details in documentation : https://www.django-rest-framework.org/api-guide/views/

AlexTorx
  • 753
  • 4
  • 9
  • I've tried both methods and still get the same outputs. I've added the import of login and authenticate to the question. Is it possible that I cant use django.contrib.auth in APIView? – Philip F. May 23 '21 at 09:28
  • I guess I went too simple. I extended my answer with more authentication / permissions classes. I managed to use a quite similar configuration in an older project. Tell me if it works. If no, do you have specific needs for using `rest_framework` instead of plain Django ? – AlexTorx May 23 '21 at 09:50
  • Well, now I get a 401 unauthorized error (due to permissions.IsAuthenticated). I guess the authentication is wrong? – Philip F. May 23 '21 at 09:59
  • I could use plain Django, but since the project is quite big now it would be a lot of work to rewrite it – Philip F. May 23 '21 at 10:00
  • Where do I set the permissions? – Philip F. May 23 '21 at 10:04
  • 1
    Yes authentication seems to be wrong. I provided you with the most basic authentication scheme. Make sure it corresponds to the you are using (could also be token, jwt, oauth, etc...). Otherwise, I don' get it and there **might** be something specific to your project / something I am not aware. – AlexTorx May 23 '21 at 10:21