DRF-Authention组件源码分析及扩展
drf 认证组件
1、认证组件源码执行流程
在该图中,我把与认证组件无关的代码都删除了,只留下了认证的代码,方便解析。每行注释的开头数字即代表了执行顺序


注意事项:
- 第5步中的self.authenticators获取流程:
- 首先,明确self代表的是request对象。则self.authenticators相当于去request对象中寻找authenticators的值。
- 其次,Request在实例化得到request对象时,在参数中可传入authenticators的值
- 通过下图流程分析:self.authenticators其实就是在视图类中定义的authentication_classes(也可在drf的配置中默认设置)


authentication_classes必须是一个列表(可迭代对象)
由于源码中指定了会执行authenticate方法,因此编写认证类时,认证函数名必须是authenticate,return时应该返回一个元组,且类需继承自BaseAuthentication
2. 实践:编写一个token认证类
假设token存储于数据库。另注意:实际工作中编写代码最好采用白名单模式。
class UnAuthentication(BaseAuthentication): # 默认继承BaseAuthentication
def authenticate(self, request): # 认证函数名固定为authenticate
# 获取token
token = request.query_params.get("token")
# 未传token
if not token:
return None
# 数据库不存在该token
user_object = models.UserInfo.objects.filter(token=token, status=1).first()
if not user_object:
return None
# token过期
if datetime.datetime.now() > user_object.token_expiry_date:
return None
return user_object, token # 认证成功,返回元组
3. 扩展点:
从认证失败后的执行过程中可发现:即使认证失败了程序也不会报错,且会继续执行后面的视图函数:
# --------认证失败----------
def _not_authenticated(self):
self._authenticator = None
if api_settings.UNAUTHENTICATED_USER:
self.user = api_settings.UNAUTHENTICATED_USER()
else:
self.user = None
if api_settings.UNAUTHENTICATED_TOKEN:
self.auth = api_settings.UNAUTHENTICATED_TOKEN()
else:
self.auth = None
那么第一个需求来了,如果我需要在认证失败后,立即让程序报错并停止执行后面的代码,该如何重写呢?
(仅供参考)答案:直接在认证失败后主动抛出错误即可:
class TokenAuthentication(BaseAuthentication):
def authenticate(self, request):
# 获取token
token = request.query_params.get("token")
# 未传token
if not token:
raise AuthenticationFailed({"code": return_code.AUTH_FAILED, "error": "认证失败,token不存在"})
# 数据库不存在该token
user_object = models.UserInfo.objects.filter(token=token, status=1).first()
if not user_object:
raise AuthenticationFailed({"code": return_code.AUTH_FAILED, "error": "认证失败123"})
# token过期
if datetime.datetime.now() > user_object.token_expiry_date:
raise AuthenticationFailed({"code": return_code.AUTH_OVERDUE, "error": "认证过期"})
return user_object, token
第二个需求:如果前端传token时不规范,有时在请求头里传,有时在查询参数中传....,那么该如何应用认证组件进行校验呢?
(仅供参考)答案:既然源码中对认证类列表进行循环了,则直接编写多个认证类即可(有多个认证类时,建议不要直接raise,否则可能导致后面的认证类无法校验)
class QueryParamsAuthentication(BaseAuthentication):
def authenticate(self, request):
# 判断token是否正确
# 1. 从查询参数获取token
token = request.query_params.get("token")
if not token:
return
# 2. 去数据库获取该token
user_obj = models.UserInfo.objects.filter(token=token).first()
# 有对象则认证成功,返回 request.user = 用户对象; request.auth = token
if user_obj:
return user_obj, token
return
def authenticate_header(self, request):
# return 'Basic realm="API"'
return "API"
class HeaderAuthentication(BaseAuthentication):
def authenticate(self, request):
# 判断token是否正确
# 1. 从请求头获取token
token = request.META.get("HTTP_AUTHORIZATION")
if not token:
return
# 2. 去数据库获取该token
user_obj = models.UserInfo.objects.filter(token=token).first()
# 有对象则认证成功,返回user和auth
if user_obj:
return user_obj, token
return
def authenticate_header(self, request):
# return 'Basic realm="API"'
return "API"
如果有多个认证类,则建议在最后一个认证类中默认抛出错误即可
class QueryParamsAuthentication(BaseAuthentication):
def authenticate(self, request):
# 判断token是否正确
# 1. 从查询参数获取token
token = request.query_params.get("token")
if not token:
return
# 2. 去数据库获取该token
user_obj = models.UserInfo.objects.filter(token=token).first()
# 有对象则认证成功,返回 request.user = 用户对象; request.auth = token
if user_obj:
return user_obj, token
return
def authenticate_header(self, request):
# return 'Basic realm="API"'
return "API"
class HeaderAuthentication(BaseAuthentication):
def authenticate(self, request):
# 判断token是否正确
# 1. 从请求头获取token
token = request.META.get("HTTP_AUTHORIZATION")
if not token:
return
# 2. 去数据库获取该token
user_obj = models.UserInfo.objects.filter(token=token).first()
# 有对象则认证成功,返回user和auth
if user_obj:
return user_obj, token
return
def authenticate_header(self, request):
# return 'Basic realm="API"'
return "API"
class NoAuthentication(BaseAuthentication):
def authenticate(self, request):
raise AuthenticationFailed({"code": 10001, "detail": "认证失败"})
DRF-Authention组件源码分析及扩展的更多相关文章
- Django框架之DRF 认证组件源码分析、权限组件源码分析、频率组件源码分析
认证组件 权限组件 频率组件
- DRF的认证组件(源码分析)
DRF认证组件(源码分析) 1. 数据库建立用户表 在drf中也给我们提供了 认证组件 ,帮助我们快速实现认证相关的功能,例如: # models.py from django.db import m ...
- Django框架之drf:8、断点调试,权限、认证、频率组件源码分析,基于APIView编写分页,异常处理
Django框架之drf 一.断点调式使用 指,在我们编写代码的时候,程序运行出现报错是无可避免的,当程序 出现报错时,我们需要找到出现报错的代码进行修改,如果时简短的代码很容易就可以找到报错位置 ...
- DRF的限流组件(源码分析)
DRF限流组件(源码分析) 限流,限制用户访问频率,例如:用户1分钟最多访问100次 或者 短信验证码一天每天可以发送50次, 防止盗刷. 对于匿名用户,使用用户IP作为唯一标识. 对于登录用户,使用 ...
- DRF的Serializer组件(源码分析)
DRF的Serializer组件(源码分析) 1. 数据校验 drf中为我们提供了Serializer,他主要有两大功能: 对请求数据校验(底层调用Django的Form和ModelForm) 对数据 ...
- ceph-csi组件源码分析(1)-组件介绍与部署yaml分析
更多ceph-csi其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 ceph-csi组件源码分析(1)-组件介绍与部署yaml分析 基于tag v3.0.0 ht ...
- 开源MyBatisGenerator组件源码分析
开源MyBatisGenerator组件源码分析 看源码前,先了解Generator能做什么? MyBatisGenerator是用来生成mybatis的Mapper接口和xml文件的工具,提供多种启 ...
- Django-restframework 源码之认证组件源码分析
Django-restframework 源码之认证组件源码分析 一 前言 之前在 Django-restframework 的流程分析博客中,把最重要的关于认证.权限和频率的方法找到了.该方法是 A ...
- element-ui 组件源码分析整理笔记目录
element-ui button组件 radio组件源码分析整理笔记(一) element-ui switch组件源码分析整理笔记(二) element-ui inputNumber.Card .B ...
- Android base-adapter-helper 源码分析与扩展
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/44014941,本文出自:[张鸿洋的博客] 本篇博客是我加入Android 开源项 ...
随机推荐
- 海豚调度调优 | 如何解决任务被禁用出现的Bug
本系列文章是 DolphinScheduler 由浅入深的教程,涵盖搭建.二开迭代.核心原理解读.运维和管理等一系列内容.适用于想对 DolphinScheduler了解或想要加深理解的读者. 祝开卷 ...
- 聊一聊SQL优化
晚上睡不着,脑子里总想着一些问题,试着写一写对于SQL查询优化的见解. 首先,数据库有自己的查询优化器,执行一条查询SQL优化器会选择最优的方式(不走索引.走索引.走哪个索引), 所以索引不是越多越好 ...
- MessageBox弹出后无响应
这几天学习了自定义模板对话框类,就是说不用系统定义的模板对话框类来创建对话框 消息处理就不用返回0了,可直接返回DefWindowProc HINSTANCE hInstance = ::GetMod ...
- C# 使用 PaddleOCRSharp 识别 图片中的文字、 使用QRCoder生成二维码
目录 使用PaddleOCRSharp识别图片中的文字 PaddleOCRSharp资料汇总: 1.将源码编译成对应的.Net 版本引入到项目中 2. 初始化PaddleOCREngine 3. 调用 ...
- .NET 网络唤醒
本文介绍下电脑设备关机的情况下如何通过网络唤醒设备,之前电源S状态 计算机Power电源状态- 唐宋元明清2188 - 博客园 (cnblogs.com) 有介绍过远程唤醒设备,后面这俩天了解多了点所 ...
- Docker高级篇:实战Redis集群!从3主3从变为4主4从
通过前面两篇,我们学会了三主三从的Redis集群搭建及主从容错切换迁移,随着业务增加,可能会有主从扩容的,所以,本文我们来实战主从扩容 PS本系列:<Docker学习系列>教程已经发布的内 ...
- drawable xx should not reference itself
背景: 在Android中新增一个xx.xml,在layer-list 的item中设定引入的drawable后,报这个提示(xx不能引用自身) 原因: 这个错误其实很离谱,但是还是有必要记一下,万一 ...
- 10 Python面向对象编程:类和对象以及和Java的对比
本篇是 Python 系列教程第 10 篇,更多内容敬请访问我的 Python 合集 这里只介绍类和对象,self.属性.方法.访问控制.类继承.方法重写在后面的文章里介绍 在Python中,类和对象 ...
- 远距离跨网络实现windows远程桌面连接
1.保证已经打开被连接电脑---远程访问---权限. 我的电脑--右键--属性--远程设置 2.选择允许连接 (选择用户和高级没有特殊设置可以不动,被连接电脑当前登陆的账号就可以满足权限) 3.打开- ...
- ICMAN液位检测方案
TA是什么? ICMAN液位检测是基于双通道比较电容式液位检测原理,来判断容器中是否有液体或者液体是否达到一定高度. 有什么用? ICMAN液位检测可以实现非接触式检测,起到高低.不同液位提醒.缺水提 ...