简体   繁体   中英

Django's user_passes_test always gets Anonymous User

I'm using the following class-based view and applying the UserPassesTestMixin to it to check some pre-conditions.

class SomeTestView(UserPassesTestMixin, APIView):

    def test_func(self):
        return check_precondition(self.request.user)

    def get(self, request):
        print("inside view")
        print("user: ", request.user)
        print("is_authenticated? ", request.user.is_authenticated)
        return Response({"status": "success"})

Below is my precondition:

def check_precondition(user):
    print("in user_passes_test")
    print("user: ", user)
    print("is_authenticated? ", user.is_authenticated)
    return True

Here's the output I am getting:

in user_passes_test
user: AnonymousUser
is_authenticated? False

inside view
user: John Doe/john@test.domain
is_authenticated? True

What I'm not able to understand is that why is the request.user anonymous inside the user_passes_test check. I want to run some precondition checks based on the user object.

Here is my sequence of middlewares:

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',
]

I'm on Django 3.1.7 and djangorestframework 3.12.3 .

What I'm not able to understand is that why is the request.user anonymous inside the user_passes_test check.

The UserPassesTestMixin does not check if the user has logged in. Sometimes you might want to check a property that can be True for non-authenticated users. For example a view that should only be visible to non-superusers, or to a user that has not registered (yet), but is based on some session variables.

You can add an extra check with the LoginRequiredMixin mixin [Django-doc] . But the way the Django REST framework handles this is normally with permission_classes [DRF-doc] :

from rest_framework import permissions
from rest_framework.permissions import IsAuthenticated

class UserPassesSomeTest(permissions.BasePermission):
    message = 'Some custom message'

    def has_permission(self, request, view):
        user = request.user
        print("in user_passes_test")
        print("user: ", user)
        print("is_authenticated? ", user.is_authenticated)
        return True

class home(APIView):
    permission_classes = (IsAuthenticated, UserPassesSomeTest)
    
    # …

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM