为什么我的 request.user 在 Django 中没有组?

Why doesn't my request.user have groups in Django?

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

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.contrib.auth.models 的默认 Django User 模型(或 AbstractUser),它们与 [=13= 具有 ManyToMany 关系].

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

一定是你的问题authentication_classes--(DRF doc) attribute (or DEFAULT_AUTHENTICATION_CLASSES settings -- (DRF doc))

在幕后,DRF 身份验证 class 会从数据库中获取 auth 用户 并仅在 指定请求实体(如TokenJWT TokenCSRF Token等)对数据库进行验证。此验证和分配过程发生在 身份验证 classes.

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

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

针对您的情况,request.user.groups 引发了一个异常,表明

  1. 收到的User对象既不是settings.AUTH_USER_MODEL nor AnonymousUser
  2. MyEndpoint 缺少 authentication_classes 属性,因此 DRF 使用 DEFAULT_AUTHENTICATION_CLASSES,其中可能包含 自定义 class,可能构建不正确

解决方案

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

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

<b>from rest_framework.authentication import TokenAuthentication</b>


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

备注

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


还没解决??

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