赞
踩
通过分析源码了解权限组件的方法调用过程
APIView 的 dispatch 中使用 initial 方法实现初始化并进行三大认证,第二步进行权限组件调用
rest_framework/views.py
class APIView(View): # ... # 定义默认权限类 permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES def initial(self, request, *args, **kwargs): # ... # 认证组件:校验用户 # 这里调用 perform_authentication 实现认证 self.perform_authentication(request) # 权限组件:校验用户权限 self.check_permissions(request) # 频率组件:限制视图接口被访问次数 self.check_throttles(request) # 权限认证 def check_permissions(self, request): # 遍历权限对象列表得到一堆权限器,进行权限认证 for permission in self.get_permissions(): # 权限类 has_permission 做权限认证 # 参数:权限对象self,请求对象request,视图类对象 # 返回值:有权限返回 True,无权限返回 False if not permission.has_permission(request, self): self.permission_denied( request, message=getattr(permission, 'message', None) ) # 获取权限 def get_permissions(self): # 由权限类定义 return [permission() for permission in self.permission_classes]
在 drf 设置文件查看默认权限配置
rest_framework/settings.py
# 默认权限类配置
DEFAULTS = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}
查看默认系统权限的实现
rest_framework/permissions.py
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 class IsAuthenticated(BasePermission): """ Allows access only to authenticated users. """ def has_permission(self, request, view): # 只有合法用户有权限,游客无任何权限: # 有值且认证通过 return bool(request.user and request.user.is_authenticated) class IsAdminUser(BasePermission): # is_staff:后台管理用户 # 后台管理用户由所有权限,游客无权限 def has_permission(self, request, view): return bool(request.user and request.user.is_staff) class IsAuthenticatedOrReadOnly(BasePermission): def has_permission(self, request, view): return bool( # 如果是读请求,不校验用户,直接返回 request.method in SAFE_METHODS or # 登录用户有所有权限,游客只读 request.user and request.user.is_authenticated )
总结以上的系统权限类:
AllowAny:游客与登录用户有所有权限
IsAuthenticated:登录用户有所有权限,游客无权限
IsAdminUser:后台管理用户由所有权限,游客无权限
IsAuthenticatedOrReadOnly:登录用户有所有权限,游客只读
settings.py
# 全局局部配置
REST_FRAMEWORK = {
# 配置默认权限类
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}
views.py
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly from rest_framework.views import APIView from rest_framework.generics import GenericAPIView from rest_framework.viewsets import GenericViewSet, ViewSet from utils.response import APIResponse # 只有登录后才能访问 # 这里认证用的是之前的 MyAuthentication class AuthenticatedAPIView(APIView): permission_classes = [IsAuthenticated] def get(self, request, *args, **kwargs): return APIResponse(0, 'Authenticated successful') # 游客只读,用户无限制 class AuthenticatedOrReadOnlyAPIView(APIView): permission_classes = [IsAuthenticatedOrReadOnly] def get(self, request, *args, **kwargs): return APIResponse(0, 'Read successful') def post(self, request, *args, **kwargs): return APIResponse(0, 'All successful')
urls.py
from django.conf.urls import url
from api import views
urlpatterns = [
url(r'^auth/$', views.AuthenticatedAPIView.as_view()),
url(r'^auth2/$', views.AuthenticatedOrReadOnlyAPIView.as_view()),
]
只有登录后才能访问
登录用户和游客可读
登录用户有所有权限
继承 BasePermission
重写 has_permission 方法
实现根据自定义权限规则,确定是否有权限
认证规则:
进行全局或局部配置
测试接口:前台在请求头携带认证信息,且默认规范用 Authorization 字段携带认证信息
自定义权限类permissions.py
from rest_framework.permissions import BasePermission, SAFE_METHODS
from django.contrib.auth.models import Group
class MyPermission(BasePermission):
def has_permission(self, request, view):
# values_list(falt=True) 获取列表转为集合,与目标求交集
group = Group.objects.filter(name='administrator').first()
groups = request.user.groups.all()
return bool(
request.method in ('GET', 'HEAD', 'OPTIONS') or
group and groups and
group in groups
)
views.py
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly from rest_framework.views import APIView from rest_framework.generics import GenericAPIView from rest_framework.viewsets import GenericViewSet, ViewSet from api.permissions import MyPermission from utils.response import APIResponse # 游客和登录用户只读,登录用户属于管理员分组无限制 class AdminOrReadOnlyAPIView(APIView): permission_classes = [MyPermission] def get(self, request, *args, **kwargs): return APIResponse(0, 'Mypermission Read successful') def post(self, request, *args, **kwargs): return APIResponse(0, 'Mypermission All successful')
urls.py
from django.conf.urls import url
from api import views
urlpatterns = [
url(r'^login/$', views.LoginView.as_view()),
url(r'^auth/$', views.AuthenticatedAPIView.as_view()),
url(r'^auth2/$', views.AuthenticatedOrReadOnlyAPIView.as_view()),
url(r'^auth3/$', views.AdminOrReadOnlyAPIView.as_view()),
]
有认证信息且正确,有所有权限
无认证信息,或有错误认证信息,无写权限
无认证信息,有读权限
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。