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 开源项 ...
随机推荐
- springboot接口入参下划线转驼峰以及返回参数驼峰转下划线实现
1.背景 在实际开发中,通常来说java里面是使用驼峰的命名规则; 但是有时候在对接其他三方平台的接口时,要求使用下划线的命名规则,这时候就涉及到如何让自己的接口满足三方平台的下划线; 实现方式有 1 ...
- inline,static inline
https://blog.csdn.net/A_BCDEF_/article/details/89485894 inline 函数被调用时,需要出栈入栈.当函数频繁被调用时,则不断地有函数出栈入栈,会 ...
- CSS2基础(part-1)
CSS2基础 基础 简介 [全称]Cascading Style Sheets,又名层叠样式表 层叠:一层一层涂上去 表:列表 样式:如文字大小,颜色,元素宽高等. CSS 描述了在屏幕.纸质.音频等 ...
- python pyqt6 设定窗口置顶
self.setWindowFlag(Qt.WindowType.WindowStaysOnTopHint)即可效果一般,页面会出现闪烁一次, # 置顶按钮 self.top_button = QPu ...
- sql server create table 给字段添加注释说明
EXEC sys.sp_addextendedproperty @name=N'MS_Description',@level1name=N'a_jcgl_data',@level2name=N'id' ...
- 单个48TB大小SQL Server数据库备份导致日志文件无法截断
单个48TB大小SQL Server数据库备份导致日志文件无法截断 SQL Server 版本:SQL Server 2019背景在一个48T大小的单数据库环境中,采用简单恢复模式,日志文件大小限制为 ...
- 常回家看看之house_of_emma
house_of_emma 前言: 相比较于house_of_kiwi(house_of_kiwi),house_of_emma的手法更加***钻,而且威力更大,条件比较宽松,只需要lagebin_a ...
- Angular 18+ 高级教程 – Component 组件 の Control Flow
前言 Control Flow 是 Angular v17 版本后推出的新模板语法,用来取代 NgIf.NgForOf.NgSwitch 这 3 个 Structure Directive. Stru ...
- 网络安全&密码学—python中的各种加密算法
网络安全&密码学-python中的各种加密算法 一.简介 数据加密是一种保护数据安全的技术,通过将数据(明文)转换为不易被未经授权的人理解的形式(密文),以防止数据泄露.篡改或滥用.加密后的数 ...
- 实用技巧:根据menuconfig定位一个驱动涉及到的源文件
根据menuconfig定位一个驱动涉及到的源文件,这个是很常用的,因为有时候你需要参考别人的驱动代码.新手不知道如何定位驱动相关源码,这篇文章将告之. 假设我手头有一块开发板,现在我想要获取板载ov ...