最新要闻
- 再不用装一堆软件了!Windows 11可原生控制RGB信仰灯
- 天天热头条丨西安最倒霉面馆顾客暴涨员工数翻4倍 很多人慕名而来:感谢大家照顾
- 通讯!男子躲查酒驾3次跳河 血检结果却为0!结果令人舒适
- 流畅度飙升!小米:MIUI 14第一批正式版机型已全量推送
- 开了比亚迪之后 男子直呼不会开油车了:跟老人机一样
- 【当前独家】配1200W永磁同步电机!宗申TL3两轮版上市:可载重300公斤
- 世界快消息!别以为老师看不出来ChatGPT生成的论文!网友:你什么水平老师心里有数
- 【世界聚看点】火狐浏览器国内最受欢迎的扩展出炉:ABP等神级工具没入围
- 真相令人大跌眼镜!研究称莫奈印象派画风实则是雾霾
- 焦点要闻:土耳其地震“震出”隐秘地层:覆盖地球的44%、颠覆板块运动
- 今日最新!女子应聘财务被要求给五六人煮饭 负责人:吃饭不方便 可以不煮
- 多色多款 杰克琼斯卫衣89元包邮:低至1.3折清仓
- 最新消息:realme 10 Pro可口可乐版发布:骁龙695 背壳logo爱了
- 【世界热闻】微信、微博全部断更!老干妈回应“退网”:经营一切正常
- 当前讯息:1TB版本太香了 真我GT Neo5供不应求 徐起:会加紧拧螺丝
- 焦点滚动:零添加:太太乐900ml*2瓶酱油最低26.4元
广告
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
python之路68 drf从入门到成神 9 drf_jwt源码执行流程、自定义用户表签发和认证、simpleui的使用、权限控制(acl、rbac)
(资料图)
drf-jwt源码执行流程(了解)
签发(登录)源码分析
登录接口,路由匹配成功,执行obtain_jwt_token ----》post请求----》ObtainJSONWebToken的post方法 path("login/",obtain_jwt_token),# ObtainJSONWebToken的post方法 继承APIView def post(self, request, *args, **kwargs): # 实例化得到序列化类 serializer = self.get_serializer(data=request.data) # 做 校验:字段自己,局部钩子,全局钩子 if serializer.is_valid(): # user:当前登录用户 user = serializer.object.get("user") or request.user # 签发的token token = serializer.object.get("token") # 构造返回格式,咱们可以自定制---- 》讲过 response_data = jwt_response_payload_handler(token, user, request) response = Response(response_data) if api_settings.JWT_AUTH_COOKIE: expiration = (datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA) response.set_cookie(api_settings.JWT_AUTH_COOKIE, token, expires=expiration, httponly=True) # 最终返回了定制的返回格式 return response return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)如何得到user,如何签发的token----》在序列化类的全局钩子中得到的user和签发的token JSONWebTokenSerializer---全局钩子---validate 前端传入,校验过后的数据----》{"username":"lqz","password":"lqz12345"} def validate(self, attrs): credentials = { # self.username_field: attrs.get(self.username_field), "username":attrs.get("username"), "password": attrs.get("password") } if all(credentials.values()): # auth模块,authenticate可以传入用户名,密码如果用户存在,就返回用户对象,如果不存在就是None # 正确的用户 user = authenticate(**credentials) if user: # 校验用户是否是活跃用户,如果禁用了,不能登录成功 if not user.is_active: msg = _("User account is disabled.") raise serializers.ValidationError(msg) # 荷载---》通过user得到荷载{id,name,email,exp} payload = jwt_payload_handler(user) return { # jwt_encode_hangdler通过荷载得到token串 "token": jwt_encode_handler(payload), "user": user } else: msg = _("Unable to log in with provided credentials.") raise serializers.ValidationError(msg) else: msg = _("Must include "{username_field}" and "password".") msg = msg.format(username_field=self.username_field) raise serializers.ValidationError(msg)"""重点 1.通过user得到荷载:payload = jwt_payload_handler(user) 2.通过荷载签发token:jwt_encode_handler(payload)"""了解: 翻译函数,只要做了国际化,放的英文,会翻译成该国语言(配置文件配置) from django.utils.translation import ugettext as _ msg = _("Unable to log in with provided credentials.")
认证(认证类)源码分析
JSONWebTokenAuthentication----》父类 BaseJSONWebTokenAuthentication---》authenticate方法 def authenticate(self, request): # 前端带在请求头中的token值 jwt_value = self.get_jwt_value(request) # 如果没有携带token 就不校验了 if jwt_value is None: return None try: # jwt_value就是token # 通过token得到荷载,中途会出错 # 出错的原因: 篡改token 过期 未知错误 payload = jwt_decode_handler(jwt_value) except jwt.ExpiredSignature: msg = _("Signature has expired.") raise exceptions.AuthenticationFailed(msg) except jwt.DecodeError: msg = _("Error decoding signature.") raise exceptions.AuthenticationFailed(msg) except jwt.InvalidTokenError: raise exceptions.AuthenticationFailed() # 如果能顺利解开,没有被异常捕获,说明token是可以信任的 # payload就可以使用,通过payload得到当前登录用户 user = self.authenticate_credentials(payload) # 返回当前登录用户,token return (user, jwt_value)# jwt_value = self.get_jwt)value(request) def get_jwt_value(self, request): # 拿到了前端请求头中传入的jwt xxxxxxxxx # auth = [jwt,xxxxxxx] auth = get_authorization_header(request).split() # "jwt" auth_header_prefix = api_settings.JWT_AUTH_HEADER_PREFIX.lower() if not auth: # 请求头中如果没带 去cookie中取 if api_settings.JWT_AUTH_COOKIE: return request.COOKIES.get(api_settings.JWT_AUTH_COOKIE) return None if smart_text(auth[0].lower()) != auth_header_prefix: return None if len(auth) == 1: msg = _("Invalid Authorization header. No credentials provided.") raise exceptions.AuthenticationFailed(msg) elif len(auth) > 2: msg = _("Invalid Authorization header. Credentials string " "should not contain spaces.") raise exceptions.AuthenticationFailed(msg) return auth[1]# 认证类配置了,如果不传jwt 不会校验 必须配合权限类一起使用
自定义用户表签发和认证
签发代码
视图类from rest_framework_jwt.settings import api_settingsjwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLERjwt_encode_handler = api_settings.JWT_ENCODE_HANDLERfrom rest_framework.viewsets import ViewSetfrom rest_framework.decorators import actionfrom rest_framework.response import Responsefrom .models import UserInfoclass UserView(ViewSet): @action(methods=["POST"], detail=False) def login(self, request, *args, **kwargs): username = request.data.get("username") password = request.data.get("password") user = UserInfo.objects.filter(username=username, password=password).first() if user: # 登录成功,签发token # 通过user得到payload payload = jwt_payload_handler(user) # 通过payload得到token token = jwt_encode_handler(payload) return Response({"code": 10000, "msg": "登录成功", "token": token}) else: return Response({"code": 10001, "msg": "用户名或密码错误"})模型类class UserInfo(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=32)路由from django.contrib import adminfrom django.urls import pathfrom rest_framework.routers import SimpleRouterfrom app01.views import UserViewrouter = SimpleRouter()router.register("user",UserView,"user")urlpatterns = [ path("admin/", admin.site.urls),]urlpatterns += router.urls
认证代码
认证类from rest_framework_jwt.settings import api_settingsjwt_decode_handler = api_settings.JWT_DECODE_HANDLERfrom rest_framework.authentication import BaseAuthenticationfrom rest_framework.exceptions import AuthenticationFailedimport jwtfrom .models import UserInfoclass JsonWebTokenAuthentication(BaseAuthentication): def authenticate(self, request): # 取出token ----》请求头中,就叫token token = request.META.get("HTTP_TOKEN") if token: try: payload = jwt_decode_handler(token) # 得到当前登录用户 # user = UserInfo.objects.get(pk=payload.get("user_id")) # 只要访问一次需要登录的接口 就会去UserInfo 表中查一次用户----》优化 user = UserInfo(id=payload.get("user_id"), username=payload.get("username")) # user= {"id":payload.get("user_id")} return user, token except jwt.ExpiredSignature: raise AuthenticationFailed("token过期") except jwt.DecodeError: raise AuthenticationFailed("token认证失败") except jwt.InvalidTokenError: raise AuthenticationFailed("token无效") except Exception as e: raise AuthenticationFailed("未知异常") raise AuthenticationFailed("token没有传,认证失败")视图类from rest_framework_jwt.settings import api_settingsjwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLERjwt_encode_handler = api_settings.JWT_ENCODE_HANDLERfrom .authentication import JsonWebTokenAuthenticationfrom rest_framework.viewsets import ViewSetfrom rest_framework.decorators import actionfrom rest_framework.response import Responsefrom .models import UserInfoclass UserView(ViewSet): @action(methods=["POST"], detail=False) def login(self, request, *args, **kwargs): username = request.data.get("username") password = request.data.get("password") user = UserInfo.objects.filter(username=username, password=password).first() if user: # 登录成功,签发token # 通过user得到payload payload = jwt_payload_handler(user) # 通过payload得到token token = jwt_encode_handler(payload) return Response({"code": 10000, "msg": "登录成功", "token": token}) else: return Response({"code": 10001, "msg": "用户名或密码错误"})class TestView(ViewSet): authentication_classes = [JsonWebTokenAuthentication] @action(methods=["GET"], detail=False) def test(self, request): return Response("ok")路由from django.contrib import adminfrom django.urls import pathfrom rest_framework.routers import SimpleRouterfrom app01.views import UserView, TestViewrouter = SimpleRouter()router.register("user", UserView, "user")# 127.0.0.1:8000/test/test/router.register("test", TestView, "test")urlpatterns = [ path("admin/", admin.site.urls),]urlpatterns += router.urls
simpleui的使用
公司里做项目,要使用权限,要快速搭建后台管理,使用django的admin直接搭建,django的admin界面不好第三方的美化: xadmin:作者不维护了 bootstrap+jquery simpleui:vue,界面更好看现阶段,一般前后端分离比较多:django+vue 带权限的前后端分离的快速开发框架 django-vue-admin
使用步骤
1.安装 pip3.8 installdjango-simpleui -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com2.在app中注册3.调整左侧导航栏 ----》 menu_display对应menus name 如果是项目的app 就menus写app 菜单可以多级,一般内部app都是一级 可以增加app外的其他链接,跟之前前后端混合项目一样的写法: show的路由 SIMPLEUI_CONFIG = { "system_keep": False, "menu_display": ["图书管理", "权限认证", "张红测试"], # 开启排序和过滤功能, 不填此字段为默认排序和全部显示, 空列表[] 为全部不显示. "dynamic": True, # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容 "menus": [ { "name": "图书管理", "app": "app01", "icon": "fas fa-code", "models": [ { "name": "图书", "icon": "fa fa-user", "url": "app01/book/" }, { "name": "出版社", "icon": "fa fa-user", "url": "app01/publisssh/" }, { "name": "作者", "icon": "fa fa-user", "url": "app01/author/" }, { "name": "作者详情", "icon": "fa fa-user", "url": "app01/authordetail/" }, ] }, { "app": "auth", "name": "权限认证", "icon": "fas fa-user-shield", "models": [ { "name": "用户", "icon": "fa fa-user", "url": "auth/user/" }, { "name": "组", "icon": "fa fa-user", "url": "auth/group/" }, ] }, { "name": "张红测试", "icon": "fa fa-file", "models": [ { "name": "Baidu", "icon": "far fa-surprise", # 第三级菜单 , "models": [ { "name": "爱奇艺", "url": "https://www.iqiyi.com/dianshiju/" # 第四级就不支持了,element只支持了3级 }, { "name": "百度问答", "icon": "far fa-surprise", "url": "https://zhidao.baidu.com/" } ] }, { "name": "大屏展示", "url": "/show/", "icon": "fab fa-github" }] } ]}4.内部app,图书管理系统 某个链接要展示的字段---》在admin.py中---》自定义按钮 @admin.register(Book)class BookAdmin(admin.ModelAdmin): list_display = ("nid", "name", "price", "publish_date", "publish") # 增加自定义按钮 actions = ["custom_button"] def custom_button(self, request, queryset): print(queryset) custom_button.confirm = "你是否执意要点击这个按钮?" # 显示的文本,与django admin一致 custom_button.short_description = "测试按钮" # icon,参考element-ui icon与https://fontawesome.com # custom_button.icon = "fas fa-audio-description" # # 指定element-ui的按钮类型,参考https://element.eleme.cn/#/zh-CN/component/button custom_button.type = "danger" # # 给按钮追加自定义的颜色 # custom_button.style = "color:black;"5.app名字显示中文,字段名字显示中文 新增,查看修改展示中文,在表模型的字段上加,verbose_name="图书名字",help_text="这里填图书名" app名字中文:apps.py---》verbose_name= "图书管理系统"6.其他配置项 SIMPLEUI_LOGIN_PARTICLES = False #登录页面动态效果 SIMPLEUI_LOGO = "https://avatars2.githubusercontent.com/u/13655483?s=60&v=4"#图标替换 SIMPLEUI_HOME_INFO = False #首页右侧github提示 SIMPLEUI_HOME_QUICK = False #快捷操作 SIMPLEUI_HOME_ACTION = False # 动作
-
python之路68 drf从入门到成神 9 drf_jwt源码执行流程、自定义用户表签发和认证、simpleui的使用、权限控制(acl、rbac)
==drf-jwt源码执行流程(了解)==签发(登录)源码分析登录接口,路由匹配成功,执行obtain_jwt_token》po...
来源: python之路68 drf从入门到成神 9 drf_jwt源码执行流程、自定义用户表签发和认证、simpleui的使用、权限控制(acl、rbac)
每日关注!导出域用户hash姿势总结
世界滚动:readelf命令读取elf文件的详细信息
再不用装一堆软件了!Windows 11可原生控制RGB信仰灯
天天热头条丨西安最倒霉面馆顾客暴涨员工数翻4倍 很多人慕名而来:感谢大家照顾
每日热门:56.函数模板
热门看点:学习打卡01- java入门
通讯!男子躲查酒驾3次跳河 血检结果却为0!结果令人舒适
流畅度飙升!小米:MIUI 14第一批正式版机型已全量推送
开了比亚迪之后 男子直呼不会开油车了:跟老人机一样
【当前独家】配1200W永磁同步电机!宗申TL3两轮版上市:可载重300公斤
世界快消息!别以为老师看不出来ChatGPT生成的论文!网友:你什么水平老师心里有数
世界热头条丨基于声网互动白板实现一个多人数独游戏
当前最新:学习笔记——尚好房项目(配置ssm环境、测试ssm环境)
《Towards Cooperation in Sequential Prisoner’s Dilemmas: a Deep Multiagent Reinfo
世界滚动:R机器学习:重复抽样在机器学习模型建立过程中的地位理解
【世界聚看点】火狐浏览器国内最受欢迎的扩展出炉:ABP等神级工具没入围
真相令人大跌眼镜!研究称莫奈印象派画风实则是雾霾
焦点要闻:土耳其地震“震出”隐秘地层:覆盖地球的44%、颠覆板块运动
今日最新!女子应聘财务被要求给五六人煮饭 负责人:吃饭不方便 可以不煮
多色多款 杰克琼斯卫衣89元包邮:低至1.3折清仓
项目终于用上了低代码,才知道为什么真香了!
机器学习-PCA
天天热消息:kx00015-顺序表--用C语言实现:删除顺序表中元素值等于x的所有元素
精彩看点:批处理脚本教程_编程入门自学教程_菜鸟教程-免费教程分享
vuex相关笔记
最新消息:realme 10 Pro可口可乐版发布:骁龙695 背壳logo爱了
【世界热闻】微信、微博全部断更!老干妈回应“退网”:经营一切正常
当前讯息:1TB版本太香了 真我GT Neo5供不应求 徐起:会加紧拧螺丝
焦点滚动:零添加:太太乐900ml*2瓶酱油最低26.4元
美少女手游《妮姬:胜利女神》即将推出PC版 推荐配置1650S
【全球聚看点】C#教程_编程入门自学教程_菜鸟教程-免费教程分享
环球时讯:【网关开发】8.Openresty 网关自定义健康检查的设计与实现
每日焦点!【0基础学爬虫】爬虫基础之爬虫的基本介绍
记录--千万别让 console.log 上生产!用 Performance 和 Memory 告诉你为什么
省选集训2023年2月9日T2
全球热讯:非油炸!吃欢天荞麦面皮10袋到手19.9元:麻酱、酸辣随便挑
世界今热点:ChatGPT版必应被华人小哥攻破:一句话“催眠”问出所有Prompt
世界热门:钙钛矿-硅光伏电池效率突破30%!可稳定工作30年
世界即时:公交车刹车提醒是2B请注意 当地回应:考虑不周将“改名”
环球热议:苹果忍不住反驳乔布斯女儿吐槽:iPhone 14比iPhone 13 Pro还要好
Entity Framework 教程_编程入门自学教程_菜鸟教程-免费教程分享
全球热文:【Spring】Bean注册注解
【当前独家】算法学习笔记(17): 快速傅里叶变换(FFT)
世界要闻:化繁为简|AIRIOT智慧水务信息化建设解决方案
环球资讯:让地球“流浪”前 先来研究下这一个更现实的威胁
女子疑吃自热火锅去世:不排除急性中毒、家属索赔176万元
当前消息!最香的i9+RTX 4080游戏本!ROG枪神7超竞版仅需18999元起
全球热讯:泰国1月份纯电动车上牌量排行:比亚迪称王、国产车霸榜
GTX 1060落魄了?《原子之心》1080P高画质需GTX 1080
环球关注:一步一腳印的 iOS App 上架和更新流程
当前快看:学习笔记——尚好房项目(项目介绍、环境搭建、配置依赖关系)
[数据结构] 二叉树的层次遍历
全球实时:JVM sandbox 实现热修复示例
《流浪地球2》全球爆火背后!《三体》导演:中国科幻的内核是文化自信
神十五航天员首次出舱视频公布:和地球同框 绝美
每日速看!方向盘助力失灵、AEB抽风!车主:百年凯迪拉克毁于LYRIQ 绝望
速递!Android 14来了:提升续航和流畅度
《狂飙》片头被指抄袭 网友放对比照跟国外一电影太相似:背后公司被扒
环球资讯:剖析字节案例,火山引擎 A/B 测试 DataTester 如何“嵌入”技术研发流程
Docker安装使用Kafka
每日动态!机器学习-KNN
全球热点评!网民称《水浒》应从中小学课文中清除 毒害更多人:浙江官方回应了
24岁生日当天崩了!腾讯QQ回应:服务器挤爆了 现已恢复
【全球报资讯】酒剑仙拿狙蚌埠住了 《仙剑奇侠传》五位角色入驻《和平精英》
如何注册 ChatGPT ,OpenAI
每日头条!A/B测试教程_编程入门自学教程_菜鸟教程-免费教程分享
环球即时看!24亿巨制大片 《速度与激情10》开启预售 片长130分钟
天天热点!魅族20 Pro外观偷跑:矩阵三摄 纯白机身太吸睛
世界今日报丨年轻人别以赚钱为目标!张朝阳称别把考试太当回事:不一定非上好大学
天天即时:中国在土耳其建造电站强震中未受损:稳定保障救援电力供应
实时焦点:微软公布ChatGPT版Bing不到48小时:申请用户量已超百万
天天热推荐:01-数据结构与算法-目录索引
环球快消息!keycloak~再说session和token
学习笔记——redis集群(定义、集群连接、查看集群、节点分配方式、插槽、集群中录入值、查询集群中的值、故障恢复)
滴滴一面:order by 调优10倍,思路是啥?
投诉不断 极氪被爆出现大规模动力故障 官方回应:会升级
焦点讯息:昆虫学硕士因表演双节棍获得工作 2000万粉大V感慨:掌握一门手艺很重要
当前报道:手机QQ崩了:显示无网络 你消息接收正常吗?
【环球新要闻】Moment推出1.55X变形镜头:iPhone也能拍出电影级超宽照片
十八罗汉分别叫什么?十八罗汉排名及顺序
马前泼水指的是什么生肖?马前泼水这个故事是什么意思?
巴黎恋人的结局是什么?巴黎恋人演员表
手净欲摸杯是什么意思?手净欲摸杯的出处是哪里?
环球观点:Linux 命令大全:2万字实现Linux自由
20088乐队现在怎么样?20088乐队现在怎么样了?
milo显示器是什么牌子?milo显示器怎么样?
ec文件是什么的简称?ec文件怎么打开?
神舟笔记本如何下载安装软件?神舟笔记本如何下载驱动?
tplink路由器怎么设置端口映射?tplink路由器怎么重新设置密码?
冰箱电磁阀怎么判断好坏?冰箱电磁阀的颜色代表什么?
票房榜前10稳了!《流浪地球2》总票房突破35亿 官方公布月球美术设计
每日信息:丰田皇冠遭车主集体投诉:空调管短了 漏水漏风
腾讯严惩《和平精英》外挂 一大批玩家一觉醒来发现被封号10年
高速特斯拉自动驾驶 驾驶员座位上睡觉!网友:保险赔吗?
世界实时:女子应聘人事被要求身高1米63以上 追问HR被回怼:不自信就不用了解了
最新资讯:keycloak~JWT没有被持久化_是因为你对方法论理解不到位
快喝不起了!农夫山泉涨价:纯净水、矿泉水啥区别、到底哪个好?
天天微头条丨在ChatGPT眼里 未来的汽车竟长这模样
天天快报!ChatGPT引发失业恐慌?这20种工作要避开:含医生、快递员