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 开源项 ...
随机推荐
- 从数据到洞察:DataOps加速AI模型开发的秘密实践大公开!
作者 | 代立冬,白鲸开源科技联合创始人&CTO 引言 在AI驱动的商业世界中,DataOps作为连接数据与洞察的桥梁,正迅速成为企业数据战略的核心. 在WOT全球技术创新大会2024·北京站 ...
- 微服务全链路跟踪:jaeger增加tag参数
微服务全链路跟踪:grpc集成zipkin 微服务全链路跟踪:grpc集成jaeger 微服务全链路跟踪:springcloud集成jaeger 微服务全链路跟踪:jaeger集成istio,并兼容u ...
- Blazor开发框架Known-V2.0.8
V2.0.8 Known是基于Blazor的企业级快速开发框架,低代码,跨平台,开箱即用,一处代码,多处运行.目前已有部分客户在使用,最近客户的项目和产品,有的在Docker中运行,有的在重新升级改造 ...
- Viper:强大的Go配置解析库
1 介绍 Viper是适用于Go应用程序的完整配置解决方案.它被设计用于在应用程序中工作,并且可以处理所有类型的配置需求和格式.目前Star 26.6k, 它支持以下特性: 设置默认值 从JSON.T ...
- 使用 Quickwit 的搜索流功能为 ClickHouse 添加全文搜索
本指南将帮助您使用 Quickwit 的搜索流功能为知名的 OLAP 数据库 ClickHouse 添加全文搜索.Quickwit 暴露了一个 REST 端点,可以极快地(每秒最多 5000 万条)流 ...
- 效率跃升16倍!火山引擎ByteHouse助力销售数据平台复杂查询效率大幅提高
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群. 销售数据,是反映市场趋势.消费者行为以及产品表现的重要指标,也是企业做出精准决策的关键依据.因此,对销售数据 ...
- 一场 Kafka CRC 异常引发的血案
一.问题概述 客户的生产环境突然在近期间歇式的收到了Kafka CRC的相关异常,异常内容如下 Record batch for partition skywalking-traces-0 at of ...
- 一个开源、跨平台的.NET UI框架 - Avalonia UI
前言 今天大姚给大家分享一个开源.免费(MIT License).跨平台的.NET UI框架:Avalonia UI. Avalonia是一个成熟稳定的平台,用于构建桌面.嵌入式.移动的和Web应用程 ...
- Spark Dataframe 转 Json
import org.apache.spark.sql.DataFrame import org.apache.spark.sql.functions._ import org.apache.spar ...
- python 浅拷贝与深拷贝
赋值引用 >>> a= {1:[1,2]}>>> b = a>>> b[2]=3>>> b {1: [1, 2], 2: 3} ...