概述
权限(permissions)与身份认证(authentication)和限流(throttling),一起决定是否应该接收请求或拒绝访问。
权限检查始终在视图的开始处运行,在允许继续执行任何其他代码之前运行。权限检查通常会用到身份认证后传入request.user和request.auth的信息来决定是否允许传入请求。
权限用于授予或拒绝将不同类别的用户访问到API的不同部分。最简单的权限是允许访问任何经过身份验证的用户,并拒绝访问任何未经身份验证的用户。这对应于REST框架中的IsAuthenticated类。稍微严格的权限控制风格是对经过身份验证的用户的允许完全访问,但对未经身份验证的用户的允许只读访问。这对应于REST框架中的IsAuthenticatedOrReadOnly类。
如何确定权限
REST Framework中权限被定义为一个权限类的列表。
运行视图的主体部分前,检查权限列表中的每个权限类。如果权限检查都失败,则会抛出一个exception.PermissionDenied或exceptions.NotAuthenticated异常,并且视图的主体不会运行。
当权限检查失败时,返回的响应的具体规则如下:
- 请求通过身份验证,但是没有通过权限验证,将返回HTTP 403 Forbidden响应。
- 请求未通过身份验证,最高优先级的认证类不使用
WWW-Authenticateheaders,则返回HTTP 403 Forbidden响应。 - 请求未通过身份验证,最高优先级的认证类使用
WWW-Authenticateheaders,则返回HTTP 401 Unauthorized响应,并且附上WWW-Authenticateheader。
设置权限策略
默认的权限策略可以通过DEFAULT_PERMISSION_CLASSES设置,例如:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
如果未设置,则默认设置为无限制访问:
'DEFAULT_PERMISSION-CLASSES': (
'rest_framework.permission.AllowAny,
)
还可以在基于APIView的视图类中单独权限策略
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
权限类 源码
BasePermission
class BasePermission(metaclass=BasePermissionMetaclass):
"""
基础权限类,重写的权限类都继承BasePermission类
"""
def has_permission(self, request, view):
"""
如果授予权限,返回True;否则返回None
"""
return True
def has_object_permission(self, request, view, obj):
"""
如果授予权限,返回True;否则返回None
"""
return True
AllowAny
class AllowAny(BasePermission):
"""
Allow any access.
This isn't strictly required, since you could use an empty
permission_classes list, but it's useful because it makes the intention
more explicit.
"""
def has_permission(self, request, view):
return True
IsAuthenticated
class IsAuthenticated(BasePermission):
"""
Allows access only to authenticated users.
"""
def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
IsAdminUser
class IsAdminUser(BasePermission):
"""
只允许管理员用户访问。
"""
def has_permission(self, request, view):
return bool(request.user and request.user.is_staff)
IsAuthenticatedOrReadOnly
class IsAuthenticatedOrReadOnly(BasePermission):
"""
如果是只读请求,不需要身份验证;
否则需要身份验证
"""
def has_permission(self, request, view):
return bool(
# SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated
)