认证

前言

用户验证用户是否合法登陆。

部分内容在DRF视图的使用及源码流程分析讲解,建议先看讲解视图的这篇文章。

使用流程

认证使用的方法流程如下:

  1. 自定义认证类,继承BaseAuthentication,并且覆写其authenticate方法。不继承BaseAuthentication也可以,但认证类中必须声明authenticateauthenticate_header两个方法。
  2. 当认证通过后应该返回两个值(一个元组),并且第一个值会传递给request.user这个属性中,第二个值将会传递给request.auth这个属性中。
  3. 如果认证失败,则抛出异常APIException或者AuthenticationFailed,它会自动捕获并返回。
  4. 当前认证类设置是全局使用还是局部使用。

自定义认证类:

完成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认证流程及源码分析的更多相关文章

  1. drf 认证校验及源码分析

    认证校验 认证校验是十分重要的,如用户如果不登陆就不能访问某些接口. 再比如用户不登陆就不能够对一个接口做哪些操作. drf中认证的写法流程如下: 1.写一个类,继承BaseAuthenticatio ...

  2. SpringMVC执行流程及源码分析

    SpringMVC流程及源码分析 前言 ​ 学了一遍SpringMVC以后,想着做一个总结,复习一下.复习写下面的总结的时候才发现,其实自己学的并不彻底.牢固.也没有学全,视频跟书本是要结合起来一起, ...

  3. DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render

    DRF框架    全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...

  4. 探索drf执行流程之APIView源码分析

    Django REST framework 简介 现在新一代web应用都开始采用前后端分离的方式来进行,淘汰了以前的服务器端渲染的方式.而实现前后端分离是通过Django REST framework ...

  5. drf 简介以及部分源码分析

    目录 复习 drf框架 全称:django-rest framework 知识点 接口 restful接口规范 基于restful规范的原生Django接口 主路由:url.py api组件的子路由: ...

  6. Android应用层View绘制流程与源码分析

    1  背景 还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原 ...

  7. Struts2请求处理流程及源码分析

    1.1 Struts2请求处理 1. 一个请求在Struts2框架中的处理步骤: a) 客户端初始化一个指向Servlet容器的请求: b) 根据Web.xml配置,请求首先经过ActionConte ...

  8. django Rest Framework----APIView 执行流程 APIView 源码分析

    在django—CBV源码分析中,我们是分析的from django.views import View下的执行流程,这篇博客我们介绍django Rest Framework下的APIView的源码 ...

  9. drf 视图使用及源码分析

    前言 drf视图的源码非常的绕,但是实现的功能却非常的神奇. 它能够帮你快速的解决ORM增删改查的重复代码,非常的方便好用. 下面是它源码中的一句话: class ViewSetMixin: &quo ...

  10. DRF中的APIView源码分析

    首先写一个简单的drf接口 from rest_framework.views import APIView from rest_framework.response import Response ...

随机推荐

  1. EntityFrameworkCore 模型自动更新(下)

    话题 上一篇我们讨论到获取将要执行的迁移操作,到这一步为止,针对所有数据库都通用,在此之后需要生成SQL脚本对于不同数据库将有不同差异,我们一起来瞅一瞅 SQLite脚本生成差异 在上一篇拿到的迁移操 ...

  2. winform,隐藏窗体

    public Form1()        {            InitializeComponent();            this.WindowState = FormWindowSt ...

  3. Kubernetes后台数据库etcd:安装部署etcd集群,数据备份与恢复

    目录 一.系统环境 二.前言 三.etcd数据库 3.1 概述 四.安装部署etcd单节点 4.1 环境介绍 4.2 配置节点的基本环境 4.3 安装部署etcd单节点 4.4 使用客户端访问etcd ...

  4. Kubernetes 监控--Alertmanager

    前面我们学习 Prometheus 的时候了解到 Prometheus 包含一个报警模块,就是我们的 AlertManager,Alertmanager 主要用于接收 Prometheus 发送的告警 ...

  5. KVM 下如何关闭 virbr0

    安装KVM 后都会发现网络接口里多了一个叫做 virbr0 的虚拟网络接口: 这是由于安装和启用了 libvirt 服务后生成的,libvirt 在服务器(host)上生成一个 virtual net ...

  6. Docker安装部署Rancher

    # 一.Rancher简介 [Rancher](https://www.cnrancher.com/rancher/)是一个开源的企业级容器管理平台.通过Rancher,企业再也不必自己使用一系列的开 ...

  7. MongoDB 分片集群的用户和权限一般操作步骤

    步骤总结: 按照mongos路由.配置副本集服务,分片副本集服务的先后顺序关闭所有节点服务 创建副本集认证的key文件,复制到每个服务所在目录 修改每个服务的配置文件,增加参数 启动每个服务 创建账号 ...

  8. 【前端必会】HtmlWebpackPlugin 和 SplitChunksPlugin 是什么?

    背景 了解什么是webpack插件,在来看一下不能不知道的两个插件 HtmlWebpackPlugin 有了这个插件,webpack执行后会自动帮我们在dist目录生成一个html文件,并且添加bun ...

  9. printf-库函数重定向、重载

    重定向:这是针对标准C语言语法来讲,指的是我们可以重新声明库函数并定义库函数的执行体 重载:这是CPP引入的新特性,即根据函数不同参数个数或参数类型来对同一函数名进行不同定义 C和CPP对重定向处理机 ...

  10. 【算法】Tarjan

    参考资料: 图论相关概念 - OI WIKI | 强连通分量 - OI WIKI 初探tarjan算法 | Tarjan,你真的了解吗 一.概念 • 子图: 对一张图 \(G=(V,E)\),若存在另 ...