DRF的权限组件(源码分析)
(资料图片仅供参考)
DRF的权限组件(源码分析)
1. 创建用户表
from django.db import models# Create your models here.class UserInfo(models.Model): role_choice = ((1, "CEO"), (2, "CTO"), (3, "CFO")) role = models.SmallIntegerField(verbose_name="类型", choices=role_choice, default=1) username = models.CharField(verbose_name="用户名", max_length=32) password = models.CharField(verbose_name="密码", max_length=32) token = models.CharField(verbose_name="TOKEN", max_length=64, null=True, blank=True)
2. 自定义权限类
from rest_framework.permissions import BasePermissionclass PermissionA(BasePermission): message = {"code": 1003, "data": "无权访问"} def has_permission(self, request, view): if request.user.role == 2: return True return False def has_object_permission(self, request, view, obj): return True
3. 视图函数中添加认证
- 局部配置(views.py)
class UserView(APIView): permission_classes = [PermissionA, ] # role权限 def get(self, request): ...
- 全局配置(settings.py)
REST_FRAMEWORK = { # 权限 "DEFAULT_PERMISSION_CLASSES": ["app01.permission.PermissionA", ]}
4. 多个权限类
当开发过程中需要用户同时具备多个权限(缺一不可)时,可以用多个权限类来实现。
权限组件内部处理机制:按照列表的顺序逐一执行 has_permission
方法,如果返回True,则继续执行后续的权限类;如果返回None或False,则抛出权限异常并停止后续权限类的执行。
# models.pyfrom django.db import modelsclass Role(models.Model): """ 角色表 """ title = models.CharField(verbose_name="名称", max_length=32)class UserInfo(models.Model): """ 用户表 """ username = models.CharField(verbose_name="用户名", max_length=32) password = models.CharField(verbose_name="密码", max_length=64) token = models.CharField(verbose_name="TOKEN", max_length=64, null=True, blank=True) roles = models.ManyToManyField(verbose_name="角色", to="Role")
# urls.pyfrom django.urls import path, re_path, includefrom app01 import viewsurlpatterns = [ path("api/auth/", views.AuthView.as_view()), path("api/order/", views.OrderView.as_view()),]
# views.pyimport uuidfrom rest_framework.views import APIViewfrom rest_framework.request import Requestfrom rest_framework.response import Responsefrom rest_framework.authentication import BaseAuthenticationfrom rest_framework.permissions import BasePermissionfrom rest_framework.exceptions import AuthenticationFailedfrom app01 import modelsclass AuthView(APIView): """ 用户登录认证 """ def post(self, request, *args, **kwargs): print(request.data) # {"username": "wupeiqi", "password": "123"} username = request.data.get("username") password = request.data.get("password") user_object = models.UserInfo.objects.filter(username=username, password=password).first() if not user_object: return Response({"code": 1000, "data": "用户名或密码错误"}) token = str(uuid.uuid4()) user_object.token = token user_object.save() return Response({"code": 0, "data": {"token": token, "name": username}})class TokenAuthentication(BaseAuthentication): def authenticate(self, request): token = request.query_params.get("token") if not token: raise AuthenticationFailed({"code": 1002, "data": "认证失败"}) user_object = models.UserInfo.objects.filter(token=token).first() if not user_object: raise AuthenticationFailed({"code": 1002, "data": "认证失败"}) return user_object, token def authenticate_header(self, request): return "Bearer realm="API""class PermissionA(BasePermission): message = {"code": 1003, "data": "无权访问"} def has_permission(self, request, view): exists = request.user.roles.filter(title="员工").exists() if exists: return True return False def has_object_permission(self, request, view, obj): return Trueclass PermissionB(BasePermission): message = {"code": 1003, "data": "无权访问"} def has_permission(self, request, view): exists = request.user.roles.filter(title="主管").exists() if exists: return True return False def has_object_permission(self, request, view, obj): return Trueclass OrderView(APIView): authentication_classes = [TokenAuthentication, ] permission_classes = [PermissionA, PermissionA] def get(self, request, *args, **kwargs): return Response({"code": 0, "data": {"user": None, "list": [1, 2, 3]}})class PayView(APIView): authentication_classes = [TokenAuthentication, ] permission_classes = [PermissionA, ] def get(self, request, *args, **kwargs): return Response({"code": 0, "data": "数据..."})
5. 关于has_object_permission
后期补充...
6. 源码分析
第三步前面的部分执行流程和前两篇文章是一样的. 这里就不过多赘述了
标签:
相关文章
DRF的权限组件(源码分析)
DRF的权限组件(源码分析)1 创建用户表fromdjango dbimportmodels Createyourmodelshere classUserInfo(model
仕佳光子(688313)2023年一季报简析:净利润减113.98%,三费占比上升明显
据证券之星公开数据整理,近期仕佳光子(688313)发布2023年一季报。根据财报显示,本报告期中仕佳光子净利
商务部:一季度我国企业承接服务外包合同额5768亿元 同比增长18.2%|当前时讯
2023年一季度,我国企业承接服务外包合同额5768亿元人民币,执行额3961亿元,同比分别增长18 2%和24 4%。
我的世界信标放在哪里比较好_我的世界信标怎么摆放才可以有全效果|天天热头条
1、九个格子方铁 黄金 钻石 绿宝石块铁铁铁铁铁铁铁铁铁铁铁铁铁信标铁铁铁铁。本文分享完毕,希望对大家有
环球热文:外交部发言人:敦促美国等发达国家审慎评估自身经济金融政策外溢影响
新华社北京4月20日电(记者马卓言)外交部发言人汪文斌20日表示,当前国际金融风险突出,同美国等发达国家
泸州老窖:公司拥有数十万吨的基酒储存能力,不同产品有不同的储存时间要求
泸州老窖00056804月21日在投资者关系平台上答复了投资者关心的问题投资者您好尊敬的董秘山东淄博烧烤火遍全
今日时讯:足球报玉昆接过大旗为云南而战 牛洪利重返梦想之地为云南打造名片_环球即时
小伙伴们好,带大家回顾下足球报玉昆接过大旗为云南而战牛洪利重返梦想之地为云南打造名片,那么小纵今天就
景甜诉广告公司侵权 广告公司涉侵权纠纷被景甜起诉|最新资讯
天眼查App显示,近日,上海网策广告有限公司新增开庭公告,案由为网络侵权责任纠纷,原告为景甜,该案将于5
以色列驻华大使在2023年世界地球日前夕呼吁各方合作 创新应对环境问题
国际在线消息(记者潘晓琳):为迎接2023年世界地球日(每年4月22日),4月19日,以色列驻华大使潘绮瑞(H E
【天天聚看点】浙江省博物馆武林馆区闭馆后再也不开了吗?
浙江省博物馆武林馆区闭馆后再也不开了吗?浙江省博物馆武林馆将于2023年5月4日正式闭馆,闭馆后将搬迁至浙
jpg和pdf哪个更清晰_jpg 和PDF的区别-天天快报
1、PDF格式是由Adobe公司推出的专为网上出版而制订的。2、它以PostscriptLevel2语言为基础,可以
新冠病毒 XBB.1.16 可能引发结膜炎,专家:无需太过担忧 快播
(人民日报健康客户端记者张爽杨晓露)4月18日,奥密克戎亚种XBB 1 16引起广泛讨论,XBB 1 16感染者出现结
2023年4月20日鸡蛋价格偏强而行金十期货4月20日讯,当前我国在产蛋鸡存栏整体仍偏低,库存不大,供应上仍能提供支撑
2023年4月20日鸡蛋价格偏强而行金十期货4月20日讯,当前我国在产蛋鸡存栏整体仍偏低,库存不大,供应上仍能
国光电器(002045):技术指标出现看涨信号-KDJ 低位金叉(04-20) 环球速递
从技术指标上看,国光电器(002045)出现看涨信号-KDJ低位金叉,后续有望上涨。资金流向数据:主力资金净流
【世界独家】甘肃省古浪县市场监管局开展农资打假保春耕专项行动
为进一步规范农资市场经营秩序,严厉打击制售假冒伪劣农资等违法行为,甘肃省古浪县市场监管局在全县范围内
黄金TD今日走势如何?2022年3月7日黄金TD价格多少?
周一(3月7日),黄金TD维持小幅上涨。本交易日,黄金TD开于372 3元 克,最高上探至380 48元 克,最低下探371
大宗交易:招商银行成交1.31亿元,成交均价34.50元(04-21)
2023年4月21日,招商银行发生3笔大宗交易,总成交380万股,成交金额1 31亿元,成交均价34 50元,成交价与收
新资讯:北方国际4月21日盘中跌幅达5%
以下是北方国际在北京时间4月21日14:47分盘口异动快照:4月21日,北方国际盘中跌幅达5%,截至14点47分,报1