05 drf源码剖析之认证
05 drf源码剖析之认证
1. 认证简述
当我们通过Web浏览器与API进行交互时,我们可以登录,然后浏览器会话将为请求提供所需的身份验证。
如果我们以编程方式与API进行交互,则需要在每个请求上显式提供身份验证凭据。
如果我们尝试在不进行身份验证的情况下创建代码段,则会收到错误消息
2. 认证的使用
创建一个认证类MyAuthentication
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
"""
Authenticate the request and return a two-tuple of (user, token).
"""
token = request.query_params.get('token')
user_object = models.UserInfo.objects.filter(token=token).first()
if user_object:
return (user_object,token)
return (None,None) # 最好继承Base类有一个约束
在需要认证的类添加authentication_classes
class OrderView(APIView):
authentication_classes = [MyAuthentication, ]
def get(self,request,*args,**kwargs):
print(request.user)
print(request.auth)
return Response('order') class UserView(APIView):
authentication_classes = [MyAuthentication,]
def get(self,request,*args,**kwargs):
print(request.user)
print(request.auth)
return Response('user')
全局使用配置,修改匿名用户的名称
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES":["utils.auth.GeneralAuthentication",], # 在全局使用认证类,列表里边写认证类的路径,不需要在类内部定义类
"UNAUTHENTICATED_USER":None, # 修改匿名用户的昵称
"UNAUTHENTICATED_TOKEN":None
}
3. 源码剖析
请求过来先执行dispatch方法
def dispatch(self, request, *args, **kwargs):
"""
- 内部封装了 authenticators = [MyAuthentication(), ]
"""
request = self.initialize_request(request, *args, **kwargs)
执行initialize_request方法,将认证对象列表封装到新的request对象中
def initialize_request(self, request, *args, **kwargs):
parser_context = self.get_parser_context(request) return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(), # [MyAuthentication(),]
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
执行get_authenticators方法,将认证类实例化成对象放到认证列表中
def get_authenticators(self):
return [ auth() for auth in self.authentication_classes ]
认证时会执行Request对象的user方法
class Request: def __init__(self, request,authenticators=None):
self._request = request
self.authenticators = authenticators or () @property
def user(self):
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate()
return self._user
_authenticate方法会执行每个认证类的authenticate方法
def _authenticate(self):
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()
认证成功后,将用户对象赋值给request.user
@user.setter
def user(self, value):
self._user = value
self._request.user = value
4. 总结
- 当用户请求过来时,执行dispatch,通过initialize_request方法,
- 找到认证的所有类并实例化成对象列表,然后将对象列表封装到新的request对象中。
- 执行下面的initial方法,经过认证的request.user方法
- 在内部会循环认证的对象列表,并执行每个对象的authenticate方法,该方法用于认证,返回值有三种,①抛出异常②返回None③返回一个元组
- 返回元组的两个值分别赋值给request.user和request.auth
05 drf源码剖析之认证的更多相关文章
- drf源码剖析系列(系列目录)
drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...
- 07 drf源码剖析之节流
07 drf源码剖析之节流 目录 07 drf源码剖析之节流 1. 节流简述 2. 节流使用 3. 源码剖析 总结: 1. 节流简述 节流类似于权限,它确定是否应授权请求.节流指示临时状态,并用于控制 ...
- 06 drf源码剖析之权限
06 drf源码剖析之权限 目录 06 drf源码剖析之权限 1. 权限简述 2. 权限使用 3.源码剖析 4. 总结 1. 权限简述 权限与身份验证和限制一起,决定了是否应授予请求访问权限. 权限检 ...
- 04 drf源码剖析之版本
04 drf源码剖析之版本 目录 04 drf源码剖析之版本 1. 版本简述 2. 版本使用 3.源码剖析 4. 总结 1. 版本简述 API版本控制使您可以更改不同客户端之间的行为.REST框架提供 ...
- 02 drf源码剖析之快速了解drf
02 drf源码剖析之快速了解drf 目录 02 drf源码剖析之快速了解drf 1. 什么是drf 2. 安装 3. 使用 3. DRF的应用场景 1. 什么是drf drf是一个基于django开 ...
- 05 flask源码剖析之配置加载
05 Flask源码之:配置加载 目录 05 Flask源码之:配置加载 1.加载配置文件 2.app.config源码分析 3.from_object源码分析 4. 总结 1.加载配置文件 from ...
- Django Rest Framework源码剖析(一)-----认证
一.简介 Django REST Framework(简称DRF),是一个用于构建Web API的强大且灵活的工具包. 先说说REST:REST是一种Web API设计标准,是目前比较成熟的一套互联网 ...
- drf源码分析系列---认证
认证的使用 from rest_framework.authentication import BaseAuthentication from api import models # 认证类 clas ...
- 01 drf源码剖析之restful规范
01 restful规范 目录 01 restful规范 1. 什么是restful规范 2.restful规范详细 1. 什么是restful规范 restful是一套规则,是程序间进行数据传输的一 ...
随机推荐
- [CF696D]Legen...
题目 点这里看题目. 分析 首先对于模式串建立 AC 自动机,并且计算出每个状态\(p\)的贡献总和\(con(p)\). 考虑一个朴素的 DP : \(f(i,p)\):当前串长度为 ...
- Redis学习笔记(二十一) 事务
文章开始啰嗦两句,写到这里共21篇关于redis的琐碎知识,没有过多的写编程过程中redis的应用,着重写的是redis命令.客户端.服务器以及生产环境搭建用到的主从.哨兵.集群实现原理,如果你真的能 ...
- BUAA_OO_2020_Unit3_总结博客
BUAA_OO_2020_Unit3_总结 2020年春季学期第十三周,OO第三单元落下帷幕,对这个单元的内容JML有了更深的理解,但也有了一些疑惑,下做总结: 一.JML语言以及工具链 经过课上JM ...
- node实现文件属性批量修改(时间属性)
前言 在默认情况下,一个文件的创建时间和修改时间是系统自己设定的,我们不能修改该的.但我们有时为了某种特殊需要,为了不让别人一眼看出文件已经给修改了,我们又需要修改文件的创建时间和修改时间.那么如何修 ...
- 浅谈HTTPS和HTTP
1.HTTP和HTTPS的基本概念 HTTP:超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务端请求和应答的标准,用于WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览 ...
- 前端笔记:div只显示两行内容,多出内容以...显示
代码: text-overflow: -o-ellipsis-lastline;overflow: hidden;text-overflow: ellipsis;display: -webkit-bo ...
- vue入门的第一天: v-on使用
v-on的使用 简介: v-on 是一个事件绑定机制,可以缩写为@ 如: <input type="button" value="按钮" v-on:cli ...
- Linux 集群安装zookeeper
系统:CentOs 7 环境:jdk 8 Zookeeper 下载地址: http://www-eu.apache.org/dist/zookeeper/stable/ 上传至服务器并解压,本人放在 ...
- BOM问题-对于php的影响
甲.BOM说明 BOM(Byte Order Mark),是UTF编码方案里用于标识编码的标准标记.这个标记是可选的,UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明当前编码方式.但如果文件 ...
- python从文件载入字典
data = np.load('dict_.npy') data = data.item() 不加最后一句,data不是字典类型