DRF-基于APIView的认证流程

简介: rest framework框架我们来看一段伪代码,MyClassView继承了APIView就有了APIView的功能class APIView(View): pass class MyClassView(APIView): pass基于Django的CBVfrom django.

rest framework框架

  • 我们来看一段伪代码,MyClassView继承了APIView就有了APIView的功能
class APIView(View):
    pass 


class MyClassView(APIView):
    pass
  • 基于Django的CBV
from django.views import View
from django.http import HttpResponse


class MyClassView(View):
    def get(self, request, *args, **kwargs):
        ret = {
            "state_code": 1000,
            "msg": "successful"
        }
        import json
        return HttpResponse(json.dumps(ret), status=201)

    def post(self, request, *args, **kwargs):
        return HttpResponse("created successful")

    def delete(self, request, *args, **kwargs):
        return HttpResponse("delete successful")
  • 基于DRF的CBV ,DRF的APIView在Django的View基础上,增加和丰富了一些功能
from django.views import View
from django.http import HttpResponse
from rest_framework.views import APIView


class MyClassView(APIView):
    def get(self, request, *args, **kwargs):
        ret = {
            "state_code": 1000,
            "msg": "successful"
        }
        import json
        return HttpResponse(json.dumps(ret), status=201)

    def post(self, request, *args, **kwargs):
        return HttpResponse("created successful")

    def delete(self, request, *args, **kwargs):
        return HttpResponse("delete successful")

原理(流程)

  • 当请求进来,先找CBV里面的dispatch方法
"""
rest_framework\views.py 
"""

 def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        # 对原生的request进行加工(丰富了一些功能)
        request = self.initialize_request(request, *args, **kwargs)
        # 获取原生request,request._request
        # 获取认证类的对象,request.authenticators
        self.request = request
        self.headers = self.default_response_headers  # deprecate?

        try:
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)

        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
  • 反射
img_dcba43f89f181da9026d8af423f89bdf.png
微信截图_20190108191829
  • request加强
img_80a8f7ff3d26b195d2d01e32a3466d23.png
微信截图_20190108200309
  • self.initialize_request方法做了什么?
img_c8c9107c6c022a2cb1d4304dd55575dd.png
微信截图_20190108200451

def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
parser_context = self.get_parser_context(request)

# 加工后新生成了Request对象
return Request(
    request,  # 原本的那个request
    parsers=self.get_parsers(),
    authenticators=self.get_authenticators(), # 认证相关
    negotiator=self.get_content_negotiator(),
    parser_context=parser_context
)
  • self.get_authenticators()方法
img_30b8b691e25bc112025174953a76dc57.png
微信截图_20190108201228
def get_authenticators(self):
"""
Instantiates and returns the list of authenticators that this view can use.
"""
# self.authentication_classes = [Dog,Cat]   auth()就是Dog和Cat对象,被装进列表里面 
return [auth() for auth in self.authentication_classes]
  • get_authenticators()方法中的self.authentication_classes,先从当前类找,有就使用当前类的authentication_classes,没有就使用父类的authentication_classes,在这里使用的是APIView里面的
img_73703e9f2a8544c3e6c421d23388a89e.png
微信截图_20190108201739
img_fe1828c471dc6144fe05dddcd90f366c.png
微信截图_20190108202231
  • 回到dispatch方法,我们可以看到其实request对象里面就有原生request和[BasicAuthentication,]
img_03eb3b96983e422cd3d0de8ddd17e15a.png
微信截图_20190108203020
  • 拿到原生request方法
img_a096e8417e4a67edcde8748ea8cb1e9d.png
微信截图_20190108203935
  • 获取认证类的对象,request.authenticators和原生request
img_a97cb0e284540a9a95c1232f7bd60299.png
微信截图_20190108204355
  • 我们可以查看dispatch方法里面的反射前做了是什么,self.initial方法
img_f4e11ecfcc5915717ecebf7765527a19.png
微信截图_20190108204819
def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
    self.format_kwarg = self.get_format_suffix(**kwargs)

        # Perform content negotiation and store the accepted info on the request
    neg = self.perform_content_negotiation(request)
    request.accepted_renderer, request.accepted_media_type = neg

        # Determine the API version, if versioning is in use.
    version, scheme = self.determine_version(request, *args, **kwargs)
    request.version, request.versioning_scheme = version, scheme

    # Ensure that the incoming request is permitted
    self.perform_authentication(request)
    self.check_permissions(request)
    self.check_throttles(request)
img_eb486d8c8da005f06f6879b117296f3a.png
微信截图_20190108205218
  • 父类的perform_authentication()方法
img_03a054c0548a988f40ee44cbf0797eaf.png
微信截图_20190108205348
img_2ab0ebc80afeec9718cbfcf1fbbf1ae6.png
微信截图_20190108205626
  • 找到user
img_f9d644a8cef6c1dda089b62893bdfdb6.png
微信截图_20190108205727
# _authenticate源码
    def _authenticate(self):
        """
        Attempt to authenticate the request using each authentication instance
        in turn.
        """
        for authenticator in self.authenticators:
            try:
                user_auth_tuple = authenticator.authenticate(self)
            except exceptions.APIException:
                self._not_authenticated()
                raise

            if user_auth_tuple is not None:
                self._authenticator = authenticator
                self.user, self.auth = user_auth_tuple
                return

        self._not_authenticated()
img_0d12d5c0ea5bf99df0a4f714d5702e74.png
微信截图_20190108210210

登陆认证

  • 我们可以编写一个自己的认证类
class MyAuthentication(object):
    def authenticate(self, request):
        token = request._request.GET.get('token')
        if not token:
            from rest_framework import exceptions
            raise exceptions.AuthenticationFailed("对不起,用户认证失败")
        return ("zhangsan", None)

  • postman验证
img_90bbf795b63173c9d95f65fba51ab612.png
微信截图_20190108211046
img_bb1f2f6511b1a2b0c83623bac2119f33.png
微信截图_20190108211238
  • 解决报错
img_ab0d10e39391e26eae1ea15e3e7630f7.png
微信截图_20190108211347
  • postman验证
img_30c31c2ae5926746a5435f93aa0bf027.png
微信截图_20190108211418
  • 解决方案2
img_f9251be98d781a8619032e04dd176db0.png
微信截图_20190108211524
  • 以后我们比如有些API需要认证才能看,我们就可以在这里进行操作

DRF认证流程:

  • 请求进来先走dispatch方法
  1. dispatch方法里面封装了request
img_3dfff30f5e09ef94a33a8b50d77f2297.png
微信截图_20190108211939
  1. 调用initial
img_10e8c5e3b5ea5d486468a6814ed741a0.png
微信截图_20190108212123
  1. 调用perform_authentication()


    img_685680eb95869834146e45ab2cddbd53.png
    微信截图_20190108212249
  2. 取user方法

img_fdb575bd8a8b40f7e9f8a73f32d03d0f.png
微信截图_20190108212402
  1. user方法里面调用了认证对象
img_0b3c7d561198563997cb82b83de33321.png
微信截图_20190108212533
  1. 遍历认证
img_dadccbc8d32f7c1f67a2b1fe2c6074c9.png
微信截图_20190108212748

使用

img_426b76792052ec5a520d11fd2fb81b08.png
微信截图_20190108213110
img_1e9a135e89f7a1c41944f026b1175eb2.png
微信截图_20190108213327
img_7513ae81f1358f3e57c03aa024a1e000.png
微信截图_20190108213349
目录
相关文章
|
存储 SQL 关系型数据库
【赵渝强老师】PostgreSQL的运行日志文件
PostgreSQL的物理存储结构包括数据文件、日志文件等。运行日志默认未开启,需配置`postgresql.conf`文件中的相关参数如`log_destination`、`log_directory`等,以记录数据库状态、错误信息等。示例配置中启用了CSV格式日志,便于管理和分析。通过创建表操作,可查看生成的日志文件,了解具体日志内容。
436 3
|
设计模式 存储 运维
微服务架构中的服务发现与注册中心设计模式
在现代软件工程实践中,微服务架构已成为构建灵活、可扩展系统的首选方案。本文将深入探讨微服务架构中至关重要的服务发现与注册中心设计模式。我们将从服务发现的基本原理出发,逐步解析注册中心的工作机制,并以Eureka和Consul为例,对比分析不同实现的优劣。文章旨在为开发者提供一套清晰的指导原则,帮助他们在构建和维护微服务系统时做出更明智的技术选择。
|
前端开发 安全 API
DRF--介绍和安装
DRF--介绍和安装
|
存储 分布式计算 安全
【云计算与大数据计算】大数据物理、集成、安全架构及阿里云飞天系统架构讲解(超详细)
【云计算与大数据计算】大数据物理、集成、安全架构及阿里云飞天系统架构讲解(超详细)
2029 0
|
关系型数据库 MySQL 网络安全
MySql出现#1036 – Table ‘ ‘ is read only 错误解决方法
MySql出现#1036 – Table ‘ ‘ is read only 错误解决方法
1117 0
|
数据中心 虚拟化
|
网络协议 前端开发 Apache
|
28天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
37860 151
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
10天前
|
人工智能 自然语言处理 监控
OpenClaw skills重构量化交易逻辑:部署+AI全自动炒股指南(2026终极版)
2026年,AI Agent领域最震撼的突破来自OpenClaw(原Clawdbot)——这个能自主规划、执行任务的智能体,用50美元启动资金创造了48小时滚雪球至2980美元的奇迹,收益率高达5860%。其核心逻辑堪称教科书级:每10分钟扫描Polymarket近千个预测市场,借助Claude API深度推理,交叉验证NOAA天气数据、体育伤病报告、加密货币链上情绪等多维度信息,捕捉8%以上的定价偏差,再通过凯利准则将单仓位严格控制在总资金6%以内,实现低风险高频套利。
4790 39