DRF认证流程及源码分析
认证
前言
用户验证用户是否合法登陆。
部分内容在DRF视图的使用及源码流程分析讲解,建议先看讲解视图的这篇文章。
使用流程
认证使用的方法流程如下:
- 自定义认证类,继承
BaseAuthentication,并且覆写其authenticate方法。不继承BaseAuthentication也可以,但认证类中必须声明authenticate和authenticate_header两个方法。 - 当认证通过后应该返回两个值(一个元组),并且第一个值会传递给
request.user这个属性中,第二个值将会传递给request.auth这个属性中。 - 如果认证失败,则抛出异常
APIException或者AuthenticationFailed,它会自动捕获并返回。 - 当前认证类设置是全局使用还是局部使用。
自定义认证类:
完成1、2、3步,异常统一返回
AuthenticationFailed。
import jwt
from jwt import exceptions
import rest_framework.exceptions as rest_exception
from rest_framework.authentication import BaseAuthentication
from rest_framework import status
from app1.models import Login
from libs.TokenManager import SALT
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.META.get("HTTP_TOKEN") # 在请求头中设置token值,获取的是HTTP_TOKEN
if not token:
raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="请在请求头中设置token值!")
try: # 解析token
verified_payload = jwt.decode(token, SALT, "HS256")
user_id, username = verified_payload["user_id"], verified_payload["username"]
user = Login.objects.filter(user=user_id, token=token).first()
if user:
return user_id, username
else:
raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="用户不存在!")
except exceptions.ExpiredSignatureError:
raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="token已经失效!")
except jwt.DecodeError:
raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="token认证失败!")
except jwt.InvalidTokenError:
raise rest_exception.AuthenticationFailed(code=status.HTTP_401_UNAUTHORIZED, detail="token非法!")
第4步:
局部认证:
在一个需要认证的CBV里面,添加authentication_classes类属性。如:
class UserAPIView(GenericAPIView, ListModelMixin):
authentication_classes = [MyAuthentication]
queryset = User.objects
serializer_class = UserSerializer
全局认证:
在settings.py里面设置:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["libs.MyAuth.MyAuthentication"]
}
在源码分析部分,大家将会明白为何这样设置。
源码分析
认证的执行,是发生在dispatch函数的过程中。

值得注意的是,封装request的时候,我们的指定的认证类也会一起封装在新的request里面。
接下来看看
get_authenticators的执行。
使用列表生成式挨个实例化了每个authentication_classes里面的认证类。而
authentication_classes读取了我们自定义的认证类。注:
如果是局部认证,那么就是我们直接给
authentication_classes赋值如果是全局认证,那么就是读取我们
settings中的DEFAULT_AUTHENTICATION_CLASSES配置项。
之后,在initial函数中,执行了三大验证,其中就有认证。

而认证直接执行了request.user,它其实是一个被@property装饰的方法。

接下来的操作都是在rest_framework.request模块里面。新封装的request就是这下面的Request类的实例。

当没有_user属性的时候,说明还未认证,则会执行 _authenticate() 方法

- 认证成功,返回元组。
- 认证失败,执行
_not_authenticated。
补充
最后,一个问题,当配置了全局认证以后,之后每个接口的访问都要执行认证,而有的借口并不需要认证或者认证的类不一样(如登陆接口),该怎么办呢?
其实很好办,全局设置以后并不影响局部设置的生效,因为局部设置的优先级大于全局设置,就比如对于登陆接口来说,我们只需要在登陆接口CBV中设置authentication_classes为空就可以了。如果有特殊需要,也可以指定其他认证类。
class LoginAPIView(APIView):
authentication_classes = []
DRF认证流程及源码分析的更多相关文章
- drf 认证校验及源码分析
认证校验 认证校验是十分重要的,如用户如果不登陆就不能访问某些接口. 再比如用户不登陆就不能够对一个接口做哪些操作. drf中认证的写法流程如下: 1.写一个类,继承BaseAuthenticatio ...
- SpringMVC执行流程及源码分析
SpringMVC流程及源码分析 前言 学了一遍SpringMVC以后,想着做一个总结,复习一下.复习写下面的总结的时候才发现,其实自己学的并不彻底.牢固.也没有学全,视频跟书本是要结合起来一起, ...
- DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
- 探索drf执行流程之APIView源码分析
Django REST framework 简介 现在新一代web应用都开始采用前后端分离的方式来进行,淘汰了以前的服务器端渲染的方式.而实现前后端分离是通过Django REST framework ...
- drf 简介以及部分源码分析
目录 复习 drf框架 全称:django-rest framework 知识点 接口 restful接口规范 基于restful规范的原生Django接口 主路由:url.py api组件的子路由: ...
- Android应用层View绘制流程与源码分析
1 背景 还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原 ...
- Struts2请求处理流程及源码分析
1.1 Struts2请求处理 1. 一个请求在Struts2框架中的处理步骤: a) 客户端初始化一个指向Servlet容器的请求: b) 根据Web.xml配置,请求首先经过ActionConte ...
- django Rest Framework----APIView 执行流程 APIView 源码分析
在django—CBV源码分析中,我们是分析的from django.views import View下的执行流程,这篇博客我们介绍django Rest Framework下的APIView的源码 ...
- drf 视图使用及源码分析
前言 drf视图的源码非常的绕,但是实现的功能却非常的神奇. 它能够帮你快速的解决ORM增删改查的重复代码,非常的方便好用. 下面是它源码中的一句话: class ViewSetMixin: &quo ...
- DRF中的APIView源码分析
首先写一个简单的drf接口 from rest_framework.views import APIView from rest_framework.response import Response ...
随机推荐
- python 基于aiohttp的异步爬虫实战
钢铁知识库,一个学习python爬虫.数据分析的知识库.人生苦短,快用python. 之前我们使用requests库爬取某个站点的时候,每发出一个请求,程序必须等待网站返回响应才能接着运行,而在整个爬 ...
- 正点原子keilkill脚本
del *.bak /s del *.ddk /s del *.edk /s del *.lst /s del *.lnp /s del *.mpf /s del *.mpj /s del *.obj ...
- JS 模块化 - 02 Common JS 模块化规范
1 Common JS 介绍 Common JS 是模块化规范之一.每个文件都是一个作用域,文件里面定义的变量/函数都是私有的,对其他模块不可见.Common JS 规范在 Node 端和浏览器端有不 ...
- Kubernetes 多租户:多租户介绍
多租户集群由多个用户和/或工作负载共享,这些用户和/或工作负载被称为"租户".多租户集群的运营方必须将租户彼此隔离,以最大限度地减少被盗用的租户或恶意租户可能对集群和其他租户造成的 ...
- Elasticsearch Painless script编程
我们之前看见了在Elasticsearch里的ingest node里,我们可以通过以下processor的处理帮我们处理我们的一些数据.它们的功能是非常具体而明确的.那么在Elasticsearch ...
- Elastic:Elasticsearch的分片管理策略
- Elasticsearch中字段的类型
在Elasticsearch中,每一个字段都有一个类型(type).以下为Elasticsearch中可以使用的类型:
- surging 将推出社区版微服务平台
前言 对于.NET大家并不陌生,有大批的企业选择.NET作为公司构建多种应用的开发平台,但是近几年随着微服务,大数据,移动端,物联网兴起,而后.NET社区生态没有跟上时代的步伐,已开始趋于没落,而其中 ...
- 基于数组或链表的学生信息管理系统(小学期C语言程序实训)
1.基于数组的学生信息管理系统 实验内容: 编写并调试程序,实现学校各专业班级学生信息的管理.定义学生信息的结构体类型,包括:学号.姓名.专业.班级.3门成绩. 实验要求: (1) main函数:以菜 ...
- 【React】学习笔记(二)——组件的生命周期、React脚手架使用
原教程视频:ttps://www.bilibili.com/video/BV1wy4y1D7JT?p=2&spm_id_from=pageDriver 目录 一.组件的生命周期 1.1.生命周 ...


