drf(django rest-framework)认证组件

复习

HyperlinkedIdentityField
​```python
功能:快速生成连接
1. publish = serializers.HyperlinkedIdentityField(view_name='ttt', lookup_field='publish_id', lookup_url_kwarg='pkk')
view_name:路由的别名,look_up_field:根据表的哪个字段,来拼路径
lookup_url_kwarg:反向解析有名分组的名字
2.写路由:url(r'^publish/(?P<pk>\d+)',views.Publish.as_view(),name="ttt")
3.实例化序列化类的时候,需要把request对象传过去
book_ser = BookSerializer(ret,many=True,context={'request':request})

数据校验

生成序列化类对象的时候,把要校验的数据(字典:前端传过来)传过来
-ser = BookSerializer(data=request.data)
-ser.is_valid()
-error_messages

认证简介

什么是验证
认证是否登陆 为什么要有认证
有些操作需登陆后才能访问 如何用认证:
也就是在使用功能前,验证其是否是登陆状态

属性,方法的查找顺序

对象>>>>类>>>>>父类

CBV知识点

一.路由层:
url(r'^books/$', views.Books.as_view()), 二.项目启动时,就会执行Books.as_view()
#as_view()源码,csrf_exempt局部禁用csrf,也就是说继承了drf的APIView的CBV都是不需要csrf认证的
@classmethod
def as_view(cls, **initkwargs):
...
#调用了父类的as_view方法,也就是View的as_view方法
view = super(APIView, cls).as_view(**initkwargs)
...
return csrf_exempt(view) #View的as_view方法,闭包函数,返回了view的内存地址
@classonlymethod
def as_view(cls, **initkwargs):
...
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
...
return view
三.所以项目启动时路由层的
url(r'^books/$', views.Books.as_view())相当于url(r'^books/$', views.Books.view) 四.当有请求过来时,系统调用Books.view方法
def view(request, *args, **kwargs):
....
#view方法返回了dispatch方法,本质了调用了dispatch方法
return self.dispatch(request, *args, **kwargs) 五.drf的dispatch源码
def dispatch(self, request, *args, **kwargs):
...
'''
self.initialize_request(request, *args, **kwargs)封装了原生request请求
返回了新的request对象,以前的request.GET 相当于新对象的request.query_params def query_params(self):
...
return self._request.GET 新的request重写了__getattr__(当.方法调用属性且当属性不存在时自动触发)
def __getattr__(self, attr):
try:
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
request = self.initialize_request(request, *args, **kwargs)
self.request = request
#所以当我们使用request.GET方法时,新对象没有GET方法,触发了__getattr__方法,执行到语句getattr(self._request, attr)获得原request对象的GET属性
'''
try:
#initial内部进行了认证,权限,频率检验
self.initial(request, *args, **kwargs)
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

总结

drf的APIView与django View的相同点
本质都是执行了dispatch方法 drf的APIView与django View的不同点
drf的APIView继承了View
派生了自己的dispatch方法
在方法中对原生request对象进行了封装 总结:CBV的本质就是执行了父类的dispatch方法
dispatch方法中会检索我们自己的CBV是否有get,post等方法
检索到了就会执行
APIView 的dispatch方法在检测之前会执行self.initial(request, *args, **kwargs)方法
此方法内部进行了认证,频率,权限控制
dispatch相当于我们学的装饰器,在执行目标函数之前或之后,可以添加我们需要的功能

认证组件:

drf的认证组件,本质就是在dispatch方法通过反射getattr()找到我们定义的方法前,增加了认证功能
#initial源码 def initial(self, request, *args, **kwargs):
...
# Ensure that the incoming request is permitted
#认证
self.perform_authentication(request)
#权限
self.check_permissions(request)
#频率
self.check_throttles(request) #认证功能源码
'''
只执行了request.user,user是私有属性,即方法被装饰成属性
此处的request已经被封装过了(封装函数在认证函数之前)
def dispatch(self, request, *args, **kwargs):
...
#封装函数
request = self.initialize_request(request, *args, **kwargs)
...
try:
#认证函数
self.initial(request, *args, **kwargs)
'''
def perform_authentication(self, request):
request.user #request.user
@property
def user(self):
...
#当我们认证通过返回了user_auth_tuple
#self.user, self.auth = user_auth_tuple会触发user的set方法
'''
@user.setter
def user(self, value):
#request有了_user属性,再调用request.user时就会直接返回request._user
self._user = value
self._request.user = value
'''
#有了_user的属性,直接返回self._user
if not hasattr(self, '_user'):
with wrap_attributeerrors():
#self是request对象,执行了request的_authenticate方法
self._authenticate()
return self._user #self._authenticate(),self是request对象
def _authenticate(self):
#self.authenticators 是request对象初始化的属性
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()

获取 self.authenticators


#Request的__init__函数
class Request(object):
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
assert isinstance(request, HttpRequest), (
'The `request` argument must be an instance of '
'`django.http.HttpRequest`, not `{}.{}`.'
.format(request.__class__.__module__, request.__class__.__name__)
)
...
#等于我们实例化传来的参数或者为空
self.authenticators = authenticators or ()
...
#何时是实例化>>>封装request请求时实例化了Request类
def initialize_request(self, request, *args, **kwargs):
parser_context = self.get_parser_context(request)
#实例化了 Request, authenticators=self.get_authenticators()
return Request(
...
#self为APIView对象
authenticators=self.get_authenticators(),
...
) #APIView的get_authenticators()方法
def get_authenticators(self):
#self为APIView对象,对象的self.authentication_classes属性
#authenticators为列表,里面放着对象
return [auth() for auth in self.authentication_classes] #APIView的authentication_classes属性
class APIView(View):
...
#自己类没有设置的话从api_settings配置文件中找
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES #settings文件,里面俩个没啥用,需要我们自定义authentication_classes,我们自定了话,按照查找顺序,会先从我们的CBV内找
DEFAULT_AUTHENTICATION_CLASSES
Default:
(
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
) 综上:drf提供的authentication_classes无法完成我们的验证需求
我们需要自定义authentication_classes里面存放我们的校验类
1.authentication_classes=[Auth,] 2.get_authenticators(self)方法返回的是我们验证类的对象的列表
def get_authenticators(self):
#self为APIView对象,对象的self.authentication_classes属性
#authenticators为列表,里面放着对象
return [auth() for auth in self.authentication_classes]
3.authenticators=self.get_authenticators()
所以authenticators就是验证类对象的列表
def initialize_request(self, request, *args, **kwargs):
parser_context = self.get_parser_context(request)
#实例化了 Request, authenticators=self.get_authenticators()
return Request(
...
#self为APIView对象
authenticators=self.get_authenticators(),
...
) 4.self.authenticators = authenticators or ()
所以self.authenticators验证类对象的列表
#Request的__init__函数
class Request(object):
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
assert isinstance(request, HttpRequest), (
'The `request` argument must be an instance of '
'`django.http.HttpRequest`, not `{}.{}`.'
.format(request.__class__.__module__, request.__class__.__name__)
)
...
#等于我们实例化传来的参数或者为空
self.authenticators = authenticators or ()
... 5.self.authenticators验证类对象的列表
所以authenticator为验证类的对象
验证类对象执行authenticate方法 #self._authenticate(),self是request对象
def _authenticate(self):
#self.authenticators 是验证类对象的列表,authenticator为验证类对象
for authenticator in self.authenticators:
try:
#验证类对象执行authenticate()方法,验证通过返回一个元组
#self为request对象,这里的参数为request对象
#我们定义自己的authenticate方法时有两个参数,一个是self,一个是request
user_auth_tuple = authenticator.authenticate(self)
#验证不通过抛出异常
except exceptions.APIException:
self._not_authenticated()
raise
#如果不为空,则列表类定义的之后的认证类都不会执行了,因为循环被return打断了
if user_auth_tuple is not None:
self._authenticator = authenticator
#self.user,self.auth解压赋值,user是私有属性,也就是方法被伪装为属性,实际调用了user的set方法,如果将当前用户返回给self.user,以后使用request._request.user就可以调用到当前用户对象了
'''
@user.setter
def user(self, value):
self._user = value
self._request.user = value
'''
self.user, self.auth = user_auth_tuple
return
self._not_authenticated()

drf认证功能的使用

1.在我们需要验证的类增加属性authentication_classes = [Auth,]
class Books(List, APIView):
authentication_classes = [Auth,]
2.定义我们的认证Auth类
from token_redis.models import User
from rest_framework.exceptions import ValidationError
from rest_framework.authentication import BaseAuthentication
class Auth(BaseAuthentication):
#必须定义authenticate方法和传入参数request
def authenticate(self,request):
token = request.query_params.get('token')
id = request.query_params.get('id')
if token:
ret = check_token(token,id)
if ret:
user = User.objects.filter(pk=id).first() return user,True
raise ValidationError('未登陆') 局部使用
在视图类中加一行:
authentication_classes = [Auth, ] 全局使用
在setting中配置
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.myauth.Auth",]
}
局部禁用
在视图类中加一行:
authentication_classes = [ ]

drf 认证功能的更多相关文章

  1. django框架-DRF工程之认证功能

    1.在Rest framework中进行了一系列的封装,这个认证功能也是被封装到在DRF工程中的一种,想要使用,首先需要在配置文件中进行相应的配置 REST_FRAMEWORK = { ’DEFAUL ...

  2. python 全栈开发,Day97(Token 认证的来龙去脉,DRF认证,DRF权限,DRF节流)

    昨日内容回顾 1. 五个葫芦娃和三行代码 APIView(views.View) 1. 封装了Django的request - request.query_params --> 取URL中的参数 ...

  3. (四) DRF认证, 权限, 节流

    一.Token 认证的来龙去脉 摘要 Token 是在服务端产生的.如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端.前端可以在每次请求的时候带上 To ...

  4. drf认证组件、权限组件、jwt认证、签发、jwt框架使用

    目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...

  5. ASP.NET Core 实现带认证功能的Web代理服务器

    引言 最近在公司开发了一个项目,项目部署架构图如下: 思路 如图中文本所述,公司大数据集群不允许直接访问外网,需要一个网关服务器代理请求,本处服务器A就是边缘代理服务器的作用. 通常技术人员最快捷的思 ...

  6. DRF认证组件流程分析

    视图函数中加上认证功能,流程见下图 import hashlib import time def get_random(name): md = hashlib.md5() md.update(byte ...

  7. DRF 认证、权限、限制

    DRF 认证.权限.限制   认证: 定义一个用户表和一个保存用户的Token表 # ======================day96======================= class ...

  8. yarn 用户导致的被挖矿 启用Kerberos认证功能,禁止匿名访问修改8088端口

    用户为dr.who,问下内部使用人员,都没有任务在跑: 结论: 恭喜你,你中毒了,攻击者利用Hadoop Yarn资源管理系统REST API未授权漏洞对服务器进行攻击,攻击者可以在未授权的情况下远程 ...

  9. 【DRF认证】

    目录 认证组件的详细用法 本文详细讲述了DRF认证组件的原理以及用法. @ * 源码剖析** 上一篇博客讲解DRF版本的时候我们都知道了,在dispatch方法里执行了initial方法来初始化我们的 ...

随机推荐

  1. 开发中mybatis的一些常见问题记录

    一.oracle数据库通过mybatis的批量插入的两种方式 方式1 insert into table_tmp (id,v1,v2,v3,v4) SELECT A.*,OSM_VIID_DEVICE ...

  2. css中如何设置透明度

    怎样在CSS样式中设置背景的透明度,下面一个具体的实例.把类为box的层设为透明.<div class="box"></div><style>. ...

  3. 洛谷P1057 传球游戏

    f[i][j]表示第i轮j拿到球的方案数 转移:f[i][j]=f[i-1][j+1] +f[i-1][j+-1].注意: 边界f[0][1]=1; 还有当j=1或N时 #include<ios ...

  4. Linux netstat命令详解和使用例子(显示各种网络相关信息)

    netstat命令用于显示与IP.TCP.UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况.netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP ...

  5. uvm_reg_map——寄存器模型(八)

    所有的寄存器都需要地址,都需要加入到地址列表中 //-------------------------------------------------------------------------- ...

  6. 微软大礼包 | 集合在线学习资源,助你秒变AI达人

    编者按:人工智能的浪潮正如火如荼地袭来,未来人工智能将大有所为,人们的生活轨迹也正在技术不断向前推进的过程中逐渐改变.人工智能不是科研人员或开发人员的专属,微软希望能够将人工智能带给每个人,从开发者到 ...

  7. shell函数的使用

    shell函数的使用比较简单,要点包括定义.参数来源.返回值: 在shell函数里,结合read命令,可以实现在执行脚本的过程中让用户选择参数,增强脚本的交互性: 脚本参数在脚本名称后面输入,函数参数 ...

  8. 微软Bot Framework文档中,关于Sign-in Card的一处代码错误及更正

    Bot Framework文档出错处网址:https://docs.botframework.com/en-us/csharp/builder/sdkreference/attachments.htm ...

  9. lastlog命令

    lastlog——检查某特定用户上次登录的时间 命令所在路径:/usr/bin/lastlog 示例1: # lastlog 列出所有用户,并显示用户最后一次登录的时间等信息 示例2: # lastl ...

  10. 陆教授浅谈5G毫米波手机天线技术的发展现状和未来的应用场景

    近日,香港城大电子工程学系讲座教授陆贵文教授荣获英国皇家工程院院士荣衔,以表彰他在推动天线研究的卓越贡献.他研发的天线由L形探针馈电微带天线.磁电耦极天线,以至5G毫米波手机天线等技术,均在天线领域影 ...