为什么Django REST框架内置的权限类有request.用户检查?



我正在写我的第一个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。同样的东西也写在docs中:

如果没有类认证,请求。的实例django.contrib.auth.models。匿名用户和请求。Auth将被设置没有。

但是这里最有趣的是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

正如您所看到的,访问该属性会触发所有的身份验证逻辑,这是下面的权限检查工作所需要的。

相关内容

最新更新