当前位置: 首页 > article >正文

Django REST framework 源码剖析-认证器详解(Authentication)

Django REST framework 源码剖析-认证器详解(Authentication)

Authentication

  • 身份验证始终在视图的最开始运行,在权限和限制检查发生之前,以及在允许任何其他代码继续之前。
  • request.user属性通常设置为contrib.auth包的user类的实例。
  • request.auth属性用于任何其他身份验证信息,例如,它可以用来表示请求签名时使用的身份验证令牌。

配置全局认证器

REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.BasicAuthentication','rest_framework.authentication.SessionAuthentication',]
}

基于 APIView 类的视图

from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIViewclass ExampleView(APIView):authentication_classes = (SessionAuthentication, BasicAuthentication)permission_classes = (IsAuthenticated,)def get(self, request, format=None):content = {'user': unicode(request.user),  # `django.contrib.auth.User` instance.'auth': unicode(request.auth),  # None}return Response(content)

基于函数视图的 @api_view 装饰器

@api_view(['GET'])
@authentication_classes((SessionAuthentication, BasicAuthentication))
@permission_classes((IsAuthenticated,))
def example_view(request, format=None):content = {'user': unicode(request.user),  # `django.contrib.auth.User` instance.'auth': unicode(request.auth),  # None}return Response(content)

未经授权和禁止响应 (Unauthorized and Forbidden responses)

  • 当未经验证的请求被拒绝许可时,有两种不同的错误代码可能是适当的。
  • HTTP 401 响应必须始终包含 WWW-Authenticate 标头,指示客户端如何进行身份验证。
  • HTTP 403 响应不包括 WWW-Authenticate 标头。
HTTP 401 未经授权
HTTP 403 权限被拒绝

API参考

BasicAuthentication

  • 此身份验证方案使用 HTTP 基本身份验证,对用户的用户名和密码进行签名。基本身份验证通常仅适用于测试。
  • 如果您在产品中使用 BasicAuthentication,您必须确保您的 API 仅在 https 上可用。您还应确保您的 API 客户端始终在登录时重新请求用户名和密码,并且不会存储这些详细信息到持久存储器中
  • 成功 提供以下凭据
request.user 将是 Django User 实例。
request.auth 将是 None
  • 失败请求头示例
WWW-Authenticate: Basic realm="api"

TokenAuthentication

  • 此身份验证方案使用简单的基于令牌的 HTTP 身份验证方案。令牌认证适用于客户端-服务器设置,例如本地桌面和移动客户端。
  • 如果您在产品中使用 TokenAuthentication,您必须确保您的 API 仅在 https 上可用
  • 使用TokenAuthentication认证方式,需要提供以下配置
INSTALLED_APPS = (...'rest_framework.authtoken'
)
  • 创建令牌提供给用户
from rest_framework.authtoken.models import Tokentoken = Token.objects.create(user=...)
print token.key
  • 客户端进行身份验证, 请求头添加如下信息
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
  • 如果想要在标头中使用不同的关键字,例如 Bearer,只需将 TokenAuthentication 子类化并设置 keyword 类变量
  • 成功通过身份验证,TokenAuthentication 提供以下凭据。
request.user 将是 Django User 实例。
request.auth 将是 rest_framework.authtoken.models.Token 实例。
  • 拒绝许可的未经身份验证的响应将导致带有相应的 WWW-Authenticate 标头的 HTTP 401 Unauthorized 响应
WWW-Authenticate: Token
  • curl 命令行工具可用于测试令牌认证 API
curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'

生成令牌 (Generating Tokens)

通过使用信号 (By using signals)
  • 如果您想要每个用户都拥有一个自动生成的令牌,您只需捕获用户的 post_save 信号即可
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):if created:Token.objects.create(user=instance)
  • 如果您已经创建了一些用户,则可以为所有现有用户生成令牌,如下所示
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Tokenfor user in User.objects.all():Token.objects.get_or_create(user=user)
通过暴露 api 端点 (By exposing an api endpoint)
  • 当使用 TokenAuthentication 时,你可能希望为客户端提供一种获取给定用户名和密码的令牌的机制。REST framework 提供了一个内置的视图来提供此行为
  • 默认的 obtain_auth_token 视图显式使用 JSON 请求和响应,而不是使用 settings 中默认的渲染器和解析器类
  • 将 obtain_auth_token 视图添加到你的 URLconf
from rest_framework.authtoken import views
urlpatterns += [url(r'^api-token-auth/', views.obtain_auth_token)
]
  • 如果需要自定义版本的 obtain_auth_token 视图,可以通过子类化 ObtainAuthToken 类,并在 url conf 中使用它来实现
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Responseclass CustomAuthToken(ObtainAuthToken):def post(self, request, *args, **kwargs):serializer = self.serializer_class(data=request.data,context={'request': request})serializer.is_valid(raise_exception=True)user = serializer.validated_data['user']token, created = Token.objects.get_or_create(user=user)return Response({'token': token.key,'user_id': user.pk,'email': user.email})
  • urls.py 如下:
urlpatterns += [url(r'^api-token-auth/', CustomAuthToken.as_view())
]
  • 通过Django admin管理token
  • xxx_app/admin.py
from rest_framework.authtoken.admin import TokenAdminTokenAdmin.raw_id_fields = ('user',)
使用 Django manage.py 命令 (Using Django manage.py command)
  • 使用以下命令生成用户令牌
./manage.py drf_create_token <username>
  • 此命令将返回给定用户的 API 令牌,如果它不存在则创建它
Generated token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b for user user1
  • 如果您想要重新生成令牌 (例如如果它已被破坏或泄露),您可以传递一个额外的参数
./manage.py drf_create_token -r <username>

SessionAuthentication

  • 此身份验证方案使用 Django 的默认会话后端进行身份验证。会话身份验证适用于与您的网站在同一会话上下文中运行的 AJAX 客户端。
  • 成功
request.user 是 Django User 实例。
request.auth 是 None
  • 失败则返回, 未经许可的未经身份验证的响应将导致 HTTP 403 Forbidden 响应

RemoteUserAuthentication

  • 此身份验证方案允许您将身份验证委托给 Web 服务器,该服务器设置 REMOTE_USER 环境变量。
  • 要使用它,你必须在你的 AUTHENTICATION_BACKENDS 设置中有 django.contrib.auth.backends.RemoteUserBackend (或者子类)
  • 默认情况下,RemoteUserBackend 为尚不存在的用户名创建 User 对象, 要更改此行为和其他行为,请参阅 Django 文档。
  • 成功通过身份验证,RemoteUserAuthentication 提供以下凭据:
request.user 是 Django User 实例。
request.auth 是 None
  • 失败则返回, 未经许可的未经身份验证的响应将导致 HTTP 403 Forbidden 响应

自定义身份验证 (Custom authentication)

  • 要实现自定义的身份验证方案,要继承 BaseAuthentication 类并且重写 .authenticate(self, request) 方法。如果认证成功,该方法应返回 (user, auth) 的二元元组,否则返回 None
  • 在某些情况下,您可能想要从 .authenticate() 方法引发 AuthenticationFailed 异常,而不是返回 None。
  • 通常,您应采取的方法是:
- 如果未尝试验证,返回 None。还将检查任何其他正在使用的身份验证方案。
- 如果尝试验证失败,则引发 AuthenticationFailed 异常。无论是否进行任何权限检查,都将立即返回错误响应,并且不会检查任何其他身份验证方案。
  • 重写 .authenticate_header(self, request) 方法。如果实现,则应返回将用作 HTTP 401 Unauthorized 响应中的 WWW-Authenticate 标头的值的字符串
  • 如果 .authenticate_header() 方法未被重写,则身份验证方案将在未经验证的请求被拒绝访问时返回 HTTP 403 Forbidden 响应。

自定义请求标头中名为 ‘X_USERNAME’ 的用户名指定的用户的任何传入请求进行身份验证

from django.contrib.auth.models import User
from rest_framework import authentication
from rest_framework import exceptionsclass ExampleAuthentication(authentication.BaseAuthentication):def authenticate(self, request):username = request.META.get('X_USERNAME')if not username:return Nonetry:user = User.objects.get(username=username)except User.DoesNotExist:raise exceptions.AuthenticationFailed('No such user')return (user, None)

相关文章:

Django REST framework 源码剖析-认证器详解(Authentication)

Django REST framework 源码剖析-认证器详解(Authentication) 身份验证始终在视图的最开始运行&#xff0c;在权限和限制检查发生之前&#xff0c;以及在允许任何其他代码继续之前。request.user属性通常设置为contrib.auth包的user类的实例。request.auth属性用于任何其他身份…...

TCP/IP三次握手的过程,为什么要3次?

一&#xff1a;过程 第一次&#xff08;SYN&#xff09;&#xff1a; 客户端发送一个带有SYN标志的TCP报文段给服务器&#xff0c;设置SYN1&#xff0c;并携带初始序列号Seqx&#xff08;随机值&#xff09;&#xff0c;进入SYN_SENT状态。等待服务器相应。 第二次&#xff08…...

Centos6安装nerdctl容器运行时

Centos6安装nerdctl容器运行时 前言Centos6安装docker---失败--不可拉取镜像docker配置国内镜像加速 Centos6安装nerdctl-full容器管理工具为Centos6配置containerd服务开机自启动设置nerdctl自动补全 前言 本文写于2025年3月22日,因一些特殊业务需要用到Centos6Docker,但Cent…...

登录验证码的接口实习,uuid,code.

UID是唯一标识的字符串,下面是百度百科关于UUID的定义&#xff1a; UUID是由一组32位数的16进制数字所构成&#xff0c;是故UUID理论上的总数为16322128&#xff0c;约等于3.4 x 10^38。也就是说若每纳秒产生1兆个UUID&#xff0c;要花100亿年才会将所有UUID用完。 UUID的标准…...

用fofa语法搜索漏洞

FOFA是一款非常强大的搜索引擎 关于对于fofa的描述是&#xff1a;FOFA&#xff08;网络空间资产检索系统&#xff09;是世界上数据覆盖更完整的IT设备搜索引擎&#xff0c;拥有全球联网IT设备更全的DNA信息。 探索全球互联网的资产信息&#xff0c;进行资产及漏洞影响范围分析…...

设计一个基于机器学习的光伏发电功率预测模型,以Python和Scikit - learn库为例

下面为你设计一个基于机器学习的光伏发电功率预测模型&#xff0c;以Python和Scikit - learn库为例。此模型借助历史气象数据和光伏发电功率数据来预测未来的光伏发电功率。 模型设计思路 数据收集&#xff1a;收集历史气象数据&#xff08;像温度、光照强度、湿度等&#xf…...

20242817李臻《Linux⾼级编程实践》第6周

20242817李臻《Linux⾼级编程实践》第6周 一、AI对学习内容的总结 Linux进程间通信&#xff08;IPC&#xff09; 1. 进程间通信基本概念 作用: 数据传输&#xff1a;进程间传递数据&#xff08;字节到兆字节级别&#xff09;。共享数据&#xff1a;多个进程操作同一数据&…...

Vue 3中的Provide与Inject

在Vue 3中&#xff0c;provide和inject机制为组件间的通信提供了一种新的方式。不同于传统的父子组件通过props传递数据的方式&#xff0c;provide和inject允许祖先组件向其所有子孙组件提供数据&#xff0c;而无需通过中间层手动传递。这使得跨层级的组件通信变得更加直接和简…...

深入解析SQL2API平台:数据交互革新者

在数字化转型持续深入的当下&#xff0c;企业对数据的高效利用与管理的需求愈发迫切。SQL2API平台应运而生&#xff0c;成为助力企业突破数据交互困境的有力工具&#xff0c;特别是它由麦聪软件基于DaaS&#xff08;数据即服务&#xff09;产品创新衍生而来&#xff0c;备受业界…...

蓝桥杯算法题分享(二)

蓝桥杯算法题分享 本文将继续分享三道经典的蓝桥杯算法题&#xff0c;包括题目描述、解题思路和 Java 代码实现&#xff0c;帮助大家更好地理解算法的应用。对算法感兴趣的朋友可以点开我的主页查看我上周分享的另三道题。 第一题&#xff1a;次数差 题目描述 x 星球有 26 只…...

实战-MySQL5.7升级8.0遇到的四个问题

近期几个项目的MySQL由5.7升级到8.0&#xff0c;升级过程中遇到四个问题&#xff0c;记录下来分享一下&#xff1a; 第一个问题详见之前的文章&#xff1a; MySQL 5.7升级8.0报异常&#xff1a;处理新增关键字 第二个问题详见之前的文章&#xff1a; MySQL 5.7升级8.0报异常…...

为什么递归用栈?动态分配用堆?

文章目录 1. 区别2. 栈空间特点优点缺点 3. 堆空间特点优点缺点 4. 栈和堆的对比5. 总结 1. 区别 栈空间和堆空间是程序内存中的两块不同区域&#xff0c;分别用于不同的用途。 栈空间&#xff1a; 栈空间是由操作系统自动管理的内存区域&#xff0c;用于存储局部变量、函数…...

Java 中装饰者模式与策略模式在埋点系统中的应用

前言 在软件开发中&#xff0c;装饰者模式和策略模式是两种常用的设计模式&#xff0c;它们在特定的业务场景下能够发挥巨大的作用。本文将通过一个实际的埋点系统案例&#xff0c;探讨如何在 Java 中运用装饰者模式和策略模式&#xff0c;以及如何结合工厂方法模式来优化代码…...

计算机视觉总结

以下是针对上述问题的详细解答,并结合代码示例进行说明: 1. 改进YOLOv5人脸检测模块,复杂光照场景准确率从98.2%提升至99.5% 优化具体过程: 光照补偿:在数据预处理阶段,采用自适应光照补偿算法,对图像进行实时增强,以减少光照变化对人脸检测的影响。数据增强:在训练…...

无人设备遥控器之调度自动化技术篇

一、技术原理 信息采集与处理&#xff1a; 通过传感器、仪表等设备采集无人设备的各种数据&#xff0c;如位置、速度、状态等。 将采集到的数据传输到调度自动化系统中进行处理和分析&#xff0c;以获取设备的实时状态。 系统建模与优化&#xff1a; 调度自动化系统会根据…...

【AI】Orin Nano+ubuntu22.04上移植YoloV11,并使用DeepStream测试成功

【AI】郭老二博文之:AI学习目录汇总 1、准备工作 使用 sdk-manager 烧写 OrinNano, JetPack版本为6.0 DP,对应操作系统为:Ubuntu22.04 参见博客:【NVIDIA】Jetson Orin Nano系列:烧写Ubuntu22.04 2、安装 PyTorch 2.1 下载依赖 1)安装onnx pip install onnx -i h…...

K8S学习之基础四十五:k8s中部署elasticsearch

k8s中部署elasticsearch 安装并启动nfs服务yum install nfs-utils -y systemctl start nfs systemctl enable nfs.service mkdir /data/v1 -p echo /data/v1 *(rw,no_root_squash) >> /etc/exports exports -arv systemctl restart nfs创建运行nfs-provisioner需要的sa账…...

如何在 Windows 上安装并使用 Postman?

Postman 是一个功能强大的API测试工具&#xff0c;它可以帮助程序员更轻松地测试和调试 API。在本文中&#xff0c;我们将讨论如何在 Windows 上安装和使用 Postman。 Windows 如何安装和使用 Postman 教程&#xff1f;...

Langchain 提示词(Prompt)

基本用法 1. 基本概念 提示词模板 是一个字符串模板&#xff0c;其中包含一些占位符&#xff08;通常是 {variable} 形式的&#xff09;&#xff0c;这些占位符可以在运行时被实际值替换。LangChain 提供了多种类型的提示词模板&#xff0c;以适应不同的使用场景。 2. 主要类…...

什么是PHP伪协议

PHP伪协议是一种特殊的URL格式&#xff0c;允许开发者以不同于传统文件路径访问和操作资源。以下是一些常见的PHP伪协议及其详细介绍&#xff1a; 常见的PHP伪协议 1. **file://** - **用途**&#xff1a;访问本地文件系统。 - **示例**&#xff1a;file:///path/to/file.txt。…...

python脚本处理excel文件

1.对比perl和python 分别尝试用perl和python处理excel文件&#xff0c;发现perl的比较复杂&#xff0c;比如说read excel就有很多方式 Spreadsheet::Read use Spreadsheet::ParseExcel 不同的method&#xff0c;对应的取sheet的cell方式也不一样。更复杂的是处理含有中文内…...

【腾讯云架构师技术沙龙2025.03.22】

大模型技术演进与行业影响分析 日期&#xff1a;2025年3月22日 主讲人&#xff1a;李建忠 《DeepSeek实战驱动行业智变—AI应用寒武纪》 整理&#xff1a;飞书语音转化DeepSeek分析汇总 一、技术演进&#xff1a;从快思考到慢思考 1. 早期争议与能力局限&#xff08;2022-202…...

【SOC 芯片设计 DFT 学习专栏 -- IDDQ 测试 与 Burn-In 测试】

文章目录 IDDQ 测试与 Burn-In 测试IDDQ 测试工作原理测试过程优点局限性示例 2. Burn-In 测试工作原理测试过程优点局限性示例 总结对比 IDDQ 测试和 Burn-in 测试&#xff1a; IDDQ 测试与 Burn-In 测试 本文将详细介绍 DFT 中 IDDQ测试 和 burn-in测试模式 IDDQ 测试 IDD…...

Axure RP 9.0教程: 基于动态面板的元件跟随来实现【音量滑块】

文章目录 引言I 音量滑块的实现步骤添加底层边框添加覆盖层基于覆盖层创建动态面板添加滑块按钮设置滑块拖动效果引言 音量滑块在播放器类APP应用场景相对较广,例如调节视频的亮度、声音等等。 I 音量滑块的实现步骤 添加底层边框 在画布中添加一个矩形框:500 x 32,圆…...

JS—call,apply,bind:1分钟掌握三者的区别

个人博客&#xff1a;haichenyi.com。感谢关注 一. 目录 一–目录二–call三–apply四–bind五–三者对比 二. call 作用&#xff1a; 立即调用函数&#xff0c;显式指定this值&#xff0c;并逐个传递参数。 语法&#xff1a; func.call(thisArg, arg1, arg2, …) 特点&…...

Linux TTY设备汇总

目录 1. ‌tty(终端设备统称) 2. ‌ptm(伪终端主设备)与pts(伪终端从设备) 3. ‌ttys(串行端口终端) 4. ‌ttyACM(USB CDC ACM设备) 5. ‌ttyGS(USB Gadget Serial设备) 主要联系‌ ‌典型应用场景‌ TTY_CORE: drivers/tty/tty_io.c:tty_register_driver…...

WPF 与 C# 开发深度剖析

一、引言 在当今的软件开发领域&#xff0c;Windows 平台依旧占据着重要的地位。而 WPF&#xff08;Windows Presentation Foundation&#xff09;作为微软推出的一款强大的用户界面&#xff08;UI&#xff09;框架&#xff0c;为开发者提供了丰富的功能和灵活的设计方式&…...

好消息!软航文档控件(NTKO WebOffice)在Chrome 133版本上提示扩展已停用的解决方案

软航文档控件现有版本依赖Manifest V2扩展技术支持才能正常运行&#xff0c;然而这个扩展技术到2025年6月在Chrome高版本上就彻底不支持了&#xff0c;现在Chrome 133开始的版本已经开始弹出警告&#xff0c;必须手工开启扩展支持才能正常运行。那么如何解决这个技术难题呢&…...

通过仿真确定抗积分饱和策略的最佳系数

通过仿真确定抗积分饱和策略的最佳系数&#xff08;如PID参数 ( K_p, K_i, K_d ) 以及抗饱和参数 ( K_{\text{back}} )、积分限幅值等&#xff09;是一个系统化的过程。以下是具体步骤和示例&#xff1a; — 1. 建立仿真模型 1.1 模型组成 被控对象&#xff1a;例如电机、温…...

消息队列(Kafka及RocketMQ等对比联系)

目录 消息队列 一、为什么使用消息队列&#xff1f;消息队列有什么优点/缺点&#xff1f;介绍下Kafka、ActiveMQ、RabbitMQ、RocketMQ有什么优点缺点&#xff0c;如何取舍&#xff1f; 1.公司业务场景是什么&#xff0c;这个业务场景有什么挑战&#xff0c;如果不用MQ有什么麻…...