|
1. 权限组件源码分析
PS:下列源码为了方便理解都进行了简化,只保留了权限相关的代码
由于视图函数中继承了APIView,因此permission_classes可在视图类中进行重写。
注意点:
- 执行权限校验前,已执行了认证流程。因此此时可通过self.user获取用户对象(认证通过的情况)
2. 实践:编写一个权限类
假设我们在认证通过后,给每个用户对象都加上表示角色的属性role。1代表普通用户, 2代表经理, 3代表BOSS:- import random
- from rest_framework.permissions import BasePermission
- from rest_framework.request import Request
- class UserPermission(BasePermission):
- message = {"code": 1001, "detail": "无权限"} # 无权限时返回的信息
- def has_permission(self, request, view):
- if request.user.role == 3:
- return True
- return False
- class ManagerPermission(BasePermission):
- message = {"code": 1001, "detail": "无权限"} # 无权限时返回的信息
- def has_permission(self, request, view):
- if request.user.role == 2:
- return True
- return False
- class BossPermission(BasePermission):
- message = {"code": 1001, "detail": "无权限"} # 无权限时返回的信息
- def has_permission(self, request, view):
- if request.user.role == 1:
- return True
- return False
复制代码
3. 源码改编
- 将权限校验中的“且”改为“或”关系,即只要有一个权限类通过校验即代表权限校验通过,继续执行后续代码:
- # 在视图类中重写源码中的check_permissions方法:
- def check_permissions(self, request):
- no_permission_objects = [] # 未通过校验的权限对象
- for permission in self.get_permissions():
- if permission.has_permission(request, self):
- # 只要有一个权限类通过校验则立即停止函数
- return
- else:
- no_permission_objects.append(permission)
- else: # 所有权限类都未通过校验
- self.permission_denied(
- request,
- message=getattr(no_permission_objects[0], 'message', None),
- code=getattr(no_permission_objects[0], 'code', None))
复制代码
- 若想要所有视图类能使用该重写的功能,可将该方法单独写成类(MyAPIView),并继承APIView;其他要使用该重写方法的视图不再继承APIView,而是继承MyAPIView
- # utils.py
- class MyAPIView(APIView):
- # 改写权限,变为"或"关系;
- def check_permissions(self, request):
- no_permission_objects = [] # 未通过校验的权限对象
- for permission in self.get_permissions():
- if permission.has_permission(request, self):
- # 只要有一个权限类通过校验则立即停止函数
- return
- else:
- no_permission_objects.append(permission)
- else: # 所有权限类都未通过校验
- self.permission_denied(
- request,
- message=getattr(no_permission_objects[0], 'message', None),
- code=getattr(no_permission_objects[0], 'code', None))
- # views.py
- class UserView(APIView): # 继承DRF的APIView,则权限判断为“且”的关系
- # 只有用户有权限
- permission_classes = [UserPermission]
- def get(self, request, pid):
- return Response("hello get")
- def post(self, request, pid):
- return Response({"nihao post!"})
- class OrderView(MyAPIView): # 用了自己改写的类MyAPIView,则权限判断为“或"的关系
- # 经理和BOSS都有权限
- permission_classes = [BossPermission, ManagerPermission]
- def get(self, request, pid):
- return Response("hello get")
- def post(self, request, pid):
- return Response({"nihao post!"})
复制代码 来源:https://www.cnblogs.com/harry6/p/18508623
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|