一、权限源码
def check_permissions(self, request):
# 获取权限组件中的权限对象
for permission in self.get_permissions():
'''
1. 由此看出,权限对象必须存在has_permission方法
2. 此处的request为加工后的request对象,self为当前视图类
3. 必须存在一个返回值,且有可能是bool值,有权限返回True,无权限返回False
'''
if not permission.has_permission(request, self):
# 权限不通过,则执行以下permission_denied方法
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
)
# 返回权限组件实例化对象
def get_permissions(self):
# 和认证组件内部一样的作用,获取permission_classes列表中的权限组件,并实例化
return [permission() for permission in self.permission_classes]
# permission_classes需要是一个列表
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
二、drf权限类
from rest_framework.permissions import
1、AllowAny
全部允许
class AllowAny(BasePermission):
def has_permission(self, request, view):
return True
2、AND
class AND:
def __init__(self, op1, op2):
self.op1 = op1
self.op2 = op2
def has_permission(self, request, view):
return (
self.op1.has_permission(request, view) and
self.op2.has_permission(request, view)
)
def has_object_permission(self, request, view, obj):
return (
self.op1.has_object_permission(request, view, obj) and
self.op2.has_object_permission(request, view, obj)
)
3、BasePermission
全部允许
class BasePermission(metaclass=BasePermissionMetaclass):
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj):
return True
4、BasePermissionMetaclass
class BasePermissionMetaclass(OperationHolderMixin, type):
pass
5、DjangoModelPermissions
class DjangoModelPermissions(BasePermission):
perms_map = {
'GET': [],
'OPTIONS': [],
'HEAD': [],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
authenticated_users_only = True
def get_required_permissions(self, method, model_cls):
kwargs = {
'app_label': model_cls._meta.app_label,
'model_name': model_cls._meta.model_name
}
if method not in self.perms_map:
raise exceptions.MethodNotAllowed(method)
return [perm % kwargs for perm in self.perms_map[method]]
def _queryset(self, view):
assert hasattr(view, 'get_queryset') \
or getattr(view, 'queryset', None) is not None, (
'Cannot apply {} on a view that does not set '
'`.queryset` or have a `.get_queryset()` method.'
).format(self.__class__.__name__)
if hasattr(view, 'get_queryset'):
queryset = view.get_queryset()
assert queryset is not None, (
'{}.get_queryset() returned None'.format(view.__class__.__name__)
)
return queryset
return view.queryset
def has_permission(self, request, view):
if getattr(view, '_ignore_model_permissions', False):
return True
if not request.user or (
not request.user.is_authenticated and self.authenticated_users_only):
return False
queryset = self._queryset(view)
perms = self.get_required_permissions(request.method, queryset.model)
return request.user.has_perms(perms)
6、DjangoModelPermissionsOrAnonReadOnly
class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions):
authenticated_users_only = False
7、DjangoObjectPermissions
class DjangoObjectPermissions(DjangoModelPermissions):
perms_map = {
'GET': [],
'OPTIONS': [],
'HEAD': [],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
def get_required_object_permissions(self, method, model_cls):
kwargs = {
'app_label': model_cls._meta.app_label,
'model_name': model_cls._meta.model_name
}
if method not in self.perms_map:
raise exceptions.MethodNotAllowed(method)
return [perm % kwargs for perm in self.perms_map[method]]
def has_object_permission(self, request, view, obj):
queryset = self._queryset(view)
model_cls = queryset.model
user = request.user
perms = self.get_required_object_permissions(request.method, model_cls)
if not user.has_perms(perms, obj):
if request.method in SAFE_METHODS:
raise Http404
read_perms = self.get_required_object_permissions('GET', model_cls)
if not user.has_perms(read_perms, obj):
raise Http404
# Has read permissions.
return False
return True
8、IsAdminUser
超级管理员
class IsAdminUser(BasePermission):
def has_permission(self, request, view):
return bool(request.user and request.user.is_staff)
9、IsAuthenticated
普通用户 and 超级管理员
class IsAuthenticated(BasePermission):
def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
10、IsAuthenticatedOrReadOnly
普通用户 and 超级管理员 or 请求方式('GET', 'HEAD', 'OPTIONS')
SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
class IsAuthenticatedOrReadOnly(BasePermission):
def has_permission(self, request, view):
return bool(
request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated
)
11、NOT
调用其他权限类,并将值取反
class NOT:
def __init__(self, op1):
self.op1 = op1
def has_permission(self, request, view):
return not self.op1.has_permission(request, view)
def has_object_permission(self, request, view, obj):
return not self.op1.has_object_permission(request, view, obj)
12、OperandHolder
class OperandHolder(OperationHolderMixin):
def __init__(self, operator_class, op1_class, op2_class):
self.operator_class = operator_class
self.op1_class = op1_class
self.op2_class = op2_class
def __call__(self, *args, **kwargs):
op1 = self.op1_class(*args, **kwargs)
op2 = self.op2_class(*args, **kwargs)
return self.operator_class(op1, op2)
13、OperationHolderMixin
class OperationHolderMixin:
def __and__(self, other):
return OperandHolder(AND, self, other)
def __or__(self, other):
return OperandHolder(OR, self, other)
def __rand__(self, other):
return OperandHolder(AND, other, self)
def __ror__(self, other):
return OperandHolder(OR, other, self)
def __invert__(self):
return SingleOperandHolder(NOT, self)
14、OR
class OR:
def __init__(self, op1, op2):
self.op1 = op1
self.op2 = op2
def has_permission(self, request, view):
return (
self.op1.has_permission(request, view) or
self.op2.has_permission(request, view)
)
def has_object_permission(self, request, view, obj):
return (
self.op1.has_object_permission(request, view, obj) or
self.op2.has_object_permission(request, view, obj)
)
15、SingleOperandHolder
class SingleOperandHolder(OperationHolderMixin):
def __init__(self, operator_class, op1_class):
self.operator_class = operator_class
self.op1_class = op1_class
def __call__(self, *args, **kwargs):
op1 = self.op1_class(*args, **kwargs)
return self.operator_class(op1)
三、权限配置
from rest_framework import settings
# 全局配置-settings.py
REMOVED_SETTINGS = [
# 认证组件配置
"DEFAULT_AUTHENTICATION_CLASSES":[
"app01.认证类路径",
...
],
# 权限组件配置
'DEFAULT_PERMISSION_CLASSES': [
'app01.权限类路径',
...
],
]
# 局部配置,在视图类中写
permission_classes=[
'认证类',
...
]
# 局部禁用,在视图类中写
permission_classes=[]