说明
校验用户权限(用户不同权限不同):
- 认证通过: 返回True 进入下一步校验(频率校验)
- 认证失败: 返回False 抛出异常,返回403权限异常
权限类型: 所有合法用户都有权限, 必须登录用户才有权限, 登录读写游客只读,
源码
权限组件入口
self.check_permissions(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 中的settings.py 中
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny', # 默认的权限认证配置
],
# 根据配置路径找到 permissions
四个权限类
权限组件自带的四个权限,默认全局配置的是AllowAny,
- 可以在settings.py中更换全局配置
- 可以在视图类中针对性的局部配置
- 可以自定义
AllowAny
游客与登陆用户都有所有权限
class AllowAny(BasePermission):
# 游客与登陆用户都有所有权限
def has_permission(self, request, view):
return True
IsAuthenticated
游客没有任何权限,登陆用户才有权限
class IsAuthenticated(BasePermission):
# 游客没有任何权限,登陆用户才有权限
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(
request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated
)
自定义权限类
1) 创建继承BasePermission的权限类
2) 重写has_permission方法
3) 实现体根据权限规则 确定有无权限
4) 进行全局或局部配置
认证规则:
i.满足设置的用户条件,代表有权限,返回True
ii.不满足设置的用户条件,代表没有权限,返回False
使用:
- permissions.py
from rest_framework.permissions import BasePermission
from django.contrib.auth.models import Group
需求: 游客只读, 登录用户只读, 只有登录用户属于管理员才有写权限
class MyPermission(BasePermission):
def has_permission(self, request, view):
# 只读接口判断
r1 = request.method in ('GET', 'HEAD', 'OPTIONS')
# group为有权限的分组
group = Group.objects.filter(name='管理员').first()
# groups为当前用户所属的所有分组
groups = request.user.groups.all()
r2 = group and groups
r3 = group in groups
# 读接口大家都有权限,写接口必须为指定分组下的登陆用户
return r1 or (r2 and r3)
- view.py
# 游客只读,登录用户只读,只有登录用户属于 管理员 分组,才可以增删改
from utils.permissions import MyPermission
class TestAdminOrReadOnlyAPIView(APIView):
permission_classes = [MyPermission] # 局部配置
# 所有用户都可以访问
def get(self, request, *args, **kwargs):
return APIResponse(0, '自定义读 OK')
# 必须是 自定义“管理员”分组 下的用户
def post(self, request, *args, **kwargs):
return APIResponse(0, '自定义写 OK')
- settings.py
REST_FRAMEWORK = {
# 权限类配置
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.IsAdminUser',
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
# 全局配置自定义的
'rest_framework.permissions.MyPermission',
],
}