上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf
默认是允许所有用户访问
源码入口:APIView.py
文件下的initial
方法下的check_permissions
def check_permissions(self, request): """ 检查是否应允许该请求。如果请求不被允许,则引发适当的异常。 """ for permission in self.get_permissions(): if not permission.has_permission(request, self): self.permission_denied( request, message=getattr(permission, 'message', None), code=getattr(permission, 'code', None) )
权限在get_permissions
方法中获取到,源码如下:
def get_permissions(self): """ 实例化并返回此视图所需的权限列表。 """ return [permission() for permission in self.permission_classes]
permission_classes
又等于api_settings.DEFAULT_PERMISSION_CLASSES
,所以我们去settings.py
文件中查找
'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', ],
我们会发现drf
默认的权限是AllowAny
,我们去看下源码:
class AllowAny(BasePermission): """ 允许任意访问。这不是严格要求的,因为您可以使用空的 permission_classes 列表,但它很有用,因为它使意图更加明确。 """ def has_permission(self, request, view): return True
我们可以看到AllowAny
继承自BasePermission
,然后定义了has_permission
方法,返回值为True
。
drf为我们提供了4个系统权限认证:
1. AllowAny 认证规则全部返回True:`return True` 游客与登录用户都有所有权限 2. IsAuthenticated 认证规则必须有登录的合法用户:`return bool(request.user and request.user.is_authenticated)` 游客没有任何权限,登录用户才有权限 3. IsAdminUser 认证规则必须是:`return bool(request.user and request.user.is_staff)` 游客没有任何权限,登录用户才有权限 4. IsAuthenticatedOrReadOnly 认证规则必须是只读请求或者是合法用户无限制 return bool( request.method in SAFE_METHODS or request.user and request.user.is_authenticated ) 游客只读,合法用户无限制
BasePermission
的权限类has_permission
方法权限规则
满足设置的用户条件,代表有权限,返回True
不满足设置的用户条件,代表有权限,返回False
自定义权限
from django.contrib.auth.models import Group from rest_framework.permissions import BasePermission class MyPermissions(BasePermission): def has_permission(self, request, view): rule1 = request.method in ['GET', 'OPTIONS', 'HEAD'] group = Group.objects.filter(name="管理员").first() groups = request.user.groups.all() rule2 = group in groups rule3 = group and groups return rule1 or (rule2 and rule3)
以上定义了3条规则
GET
、OPTIONS
、HEAD
游客和用户都可以访问接下里我们定义视图
class TestView(APIView): permission_classes = [MyPermissions] def get(self, request, *args, **kwargs): print(request.user) return APIResponse(data_msg="所有用户都可以访问") def post(self, request, *args, **kwargs): print(request.user) return APIResponse(data_msg="只有管理员用户可以访问")
视图中只是添加了permission_classes = [MyPermissions]
属与局部配置,也就是自定义的权限只针对此视图,其他视图还是默认的全局配置,如果我们还有其他的关于权限的需求,只需要在自定义的权限类中写逻辑即可