【问题标题】:Why doesn't my request.user have groups in Django?为什么我的 request.user 在 Django 中没有组?
【发布时间】:2021-01-08 15:42:34
【问题描述】:

我有一个使用 Django Rest Framework 构建的端点,现在我想向其添加权限,以便只有属于某个组的用户才能访问端点。所以我使用基于令牌的访问并受到this example 的启发,我正在尝试使用以下代码:

class ReadPermission(BasePermission):
    def has_permission(self, request, view):
        return request.user.groups.filter(name=settings.GROUP_POST_DATA).exists()

class MyEndpoint(mixins.ListModelMixin, viewsets.GenericViewSet):
    permission_classes = [IsAuthenticated, ReadPermission]
    http_method_names = ['get']
    # etc

但不幸的是,我收到了AttributeError: 'User' object has no attribute 'groups'

为什么用户对象没有组?

【问题讨论】:

  • 如果是自定义的,你能显示你正在使用的身份验证类吗?可能是附加到请求的用户对象不是正确的
  • 可以添加Django和Django REST Framework的版本吗?
  • 你的代码片段是正确的;你能显示 MyEndpoint 的注册(在 urls.py 中)吗?我还会在 ReadPermission .has_permission() 中插入一个断点(pdb.set_trace() 可以)并检查“request.user”。是用户吗?然后尝试“dir(request.user)”来显示对象的属性。是否存在“组”?最后:request.user.groups.all()。你能看到一组查询集吗?

标签: python django django-rest-framework permissions authorization


【解决方案1】:

似乎您没有使用或继承 django.contrib.auth.models 的默认 Django User 模型(或 AbstractUser),它们与 Groups 具有多对多关系。

如果您使用一些自定义 User 模型,您可以简单地将上述模块中的 PermissionsMixin 添加到继承 (see docs)。还要确保django.contrib.auth 在您的INSTALLED_APPS 设置中。

【讨论】:

  • 感谢您的建议。不幸的是,我没有定义自定义用户模型。另外,我将django.contrib.auth 添加到INSTALLED_APPS。我在视图中添加了一个断点来检查元素。您知道我如何从 pdb 中检查它以检查它是否具有多对多关系吗?
【解决方案2】:

问题一定出在你authentication_classes--(DRF doc)属性(或DEFAULT_AUTHENTICATION_CLASSES settings -- (DRF doc)

在幕后,DRF 身份验证类从数据库中获取 auth 用户,并仅在 指定的请求实体之后将其分配给 request 对象(如 TokenJWT TokenCSRF Token 等)针对数据库进行了验证。此验证和分配过程发生在身份验证类中。

假设,如果 Django 或 DRF 无法识别请求的用户,它会将 AnonymousUser--(Django doc) 对象分配给 request

幸运的是,AnonymousUser 对象确实具有 groupsuser_permissions 属性。这意味着,request.user.groupsrequest.user.user_permissions 都不会引发任何 AttributeError 异常。 p>

谈到你的情况,request.user.groups 引发了一个异常,这表明

  1. 接收到的User对象既不是settings.AUTH_USER_MODEL也不是AnonymousUser
  2. MyEndpoint 缺少 authentication_classes 属性,因此 DRF 使用 DEFAULT_AUTHENTICATION_CLASSES,它可能包含 自定义类,可能无法正确构建强>

解决方案

我假设您需要使用基于令牌的身份验证系统,所以我在这里使用DRF's TokenAuthentication -- (DRF doc)

在视图类中分配 authentication_classes = (TokenAuthentication,) 肯定会将 request.user 设置为 settings.AUTH_USER_MODEL 实例或 AnonymousUser

from rest_framework.authentication import TokenAuthentication


class MyEndpoint(
    mixins.ListModelMixin,
    viewsets.GenericViewSet
):
    permission_classes = [IsAuthenticated, ReadPermission]
    http_method_names = ['get']
    authentication_classes = (TokenAuthentication,)

注意

问题不属于permission_classes设置,而是authentication_classes


还没有解决??

  1. 它可以重现吗? (您的代码 sn-p 在我的机器上运行良好,可能是每个人的机器)如果是这样,请添加重现步骤
  2. MIDDLEWARE 的值是多少?你有定制的吗?
  3. UNAUTHENTICATED_USER 的值是多少?

【讨论】:

    猜你喜欢
    • 2013-06-23
    • 1970-01-01
    • 2014-07-07
    • 2011-07-26
    • 2018-09-17
    • 2022-10-06
    • 2014-08-20
    • 1970-01-01
    • 2019-12-30
    相关资源
    最近更新 更多