【问题标题】:Django's user_passes_test always gets Anonymous UserDjango 的 user_passes_test 总是得到匿名用户
【发布时间】:2021-11-24 17:16:43
【问题描述】:

我正在使用以下基于类的视图并将UserPassesTestMixin 应用于它以检查一些先决条件。

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"})

以下是我的前提条件:

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

这是我得到的输出:

in user_passes_test
user: AnonymousUser
is_authenticated? False

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

我无法理解的是,为什么 request.user 匿名在 user_passes_test 检查中。我想根据用户对象运行一些前置条件检查。

这是我的中间件序列:

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

我在 Django 3.1.7 和 djangorestframework 3.12.3

【问题讨论】:

    标签: python django django-rest-framework django-views


    【解决方案1】:

    我无法理解的是,为什么 request.user 匿名在 user_passes_test 支票内。

    UserPassesTestMixin 确实检查用户是否已登录。有时您可能希望为未经过身份验证的用户检查可以是True 的属性。例如,应该只对非超级用户或尚未注册(尚未)但基于某些会话变量的用户可见的视图。

    您可以使用LoginRequiredMixin mixin [Django-doc] 添加额外检查。但是 Django REST 框架处理这个问题的方式通常是 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)
        
        # …

    【讨论】:

    • 谢谢,但对于我的特定用例,我无法访问视图定义,因为它们来自使用功能视图的包 (social_django)。相反,我希望在我的 url 中使用 user_passes_test 装饰器来包装视图引用并调用自定义前提条件来检查使用是否已登录。(我只想允许未登录用户使用 URL)
    • 另外,根据文档,user_passes_test 应该按照此处的定义具有完整的 request.user 对象,允许检查它们是否经过身份验证或匿名。 (参考:docs.djangoproject.com/en/3.2/topics/auth/default/…
    • @Aldo:他们通过了request.user,这是正确的。但是如果用户没有登录,仍然有一个request.user:它被设置为一个AnonymousUser 对象。所以您可以检查用户是否通过了身份验证,但它不是user_passes_test 本身完成的。
    • @Aldo: 至于装饰视图,你可以使用django-decorator-include包来装饰urls.py中的include(..)
    • 谢谢,我确实在使用django-decorator-include,但仍然存在的问题是我的装饰器(user_passes_test)无法检查我想要检查的条件,因为问题中突出显示了主要问题.即使是经过身份验证的用户也会以匿名用户的身份出现,这是主要问题。
    猜你喜欢
    • 2018-05-21
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    • 2015-12-04
    • 2011-09-25
    • 2019-06-26
    • 2017-07-07
    • 1970-01-01
    相关资源
    最近更新 更多