为什么 Django REST Framework 内置权限 类 有 request.user 检查?

Why do Django REST Framework builtin permission classes have request.user check?

我正在编写我的第一个 DRF 项目,我对如何实现内置 DRF 许可 类 感兴趣 - 例如 IsAuthenticatedIsAdminUser

rest_framework/permissions.py中您可以找到以下代码:

class IsAdminUser(BasePermission):
    ...
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_staff)

class IsAuthenticated(BasePermission):
    ...
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated)

如您所见,类 都在第二个条件之前检查 request.user。 可能出于某种原因需要它,但我不明白为什么。

我首先想到的是 request.user 对象可能具有 None 值,或者某些对象没有 is_staffis_authenticated 属性,在这种情况下request.user.is_staffrequest.user.is_authenticated 将导致 AttributeError。 我做了一些实验,即使我发送未经身份验证的请求,request.user 也会指向 AnonymousUser。同样的事情写在文档中:

If no class authenticates, request.user will be set to an instance of django.contrib.auth.models.AnonymousUser, and request.auth will be set to None.

但这里最有趣的是 AnonymousUser 对象 实际上有 is_staffis_authenticated 属性!两者都设置为 False。 那么为什么要先检查 request.user 而不是直接检查 request.user.is_staffrequest.user.is_authenticated 条件呢?

request.user 是一种触发 django-rest-framework 中所有身份验证逻辑的方法。这是一个惰性 属性,必须在 request.user.is_authenticated 等属性可用之前访问。

django-rest-framework中的相关代码:

class Request:
    …
    @property
    def user(self):
        """
        Returns the user associated with the current request, as authenticated
        by the authentication classes provided to the request.
        """
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():
                self._authenticate()
        return self._user

如您所见,访问 属性 会触发所有身份验证逻辑,这是以下权限检查工作所必需的。