补充

  1 认证 权限 频率组件原理基本相同

  2 认证相关:

    session cookie token 认证相关的  这里用token

    token 1 有时间限制,超时则失效 2 每次登录更换一个token

  3 访问频率限制

    1 防止同一时间多次访问的黑客攻击,增加服务器压力。

  4 我们的解析 认证 权限 频率 是在用户get post等请求之前就做好了的

  5 uuid随机数模块,uuid.uuid4()获取随机数

认证 权限 频率组件操作流程

认证需要建立user表和token表

# 用户表
class User(models.Model):
user=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
type=((1,"VIP"),(2,"SVIP"),(3,"SSSVIP"))
user_type=models.IntegerField(choices=type) # token表
class UserToken(models.Model):
user=models.OneToOneField("User")
token=models.CharField(max_length=128)

用户登录视图添加token

from app01.models import User,UserToken

class LoginView(APIView):
"""
1000:成功
1001:用户名或者密码错误
1002:异常错误
"""
def post(self,request): response = {"code": 1000, "msg": None, "user": None}
try:
print(request.data)
user = request.data.get("user")
pwd = request.data.get("pwd") user = User.objects.filter(user=user, pwd=pwd).first()
import uuid
random_str = uuid.uuid4()
if user: UserToken.objects.update_or_create(user=user, defaults={"token": random_str})
response["user"] = user.user
response["token"] = random_str
else:
response["code"] = 1001
response["msg"] = "用户名或者密码错误" except Exception as e:
response["code"]=1002
response["msg"]=str(e) return Response(response)

认证自定义的模块

其中继承 BaseAuthentication除了类本生加的功能外还继承了header方法,如果不继承需要自己写一个header方法,否则会报错!

from app01.models import UserToken
from rest_framework.exceptions import AuthenticationFailed from rest_framework.authentication import BaseAuthentication class UserAuth(BaseAuthentication): def authenticate(self,request): token=request.query_params.get("token") usertoken=UserToken.objects.filter(token=token).first()
if usertoken:
return usertoken.user,usertoken.token
else:
raise AuthenticationFailed("认证失败!")

权限组件自定义的模块

from rest_framework.permissions import AllowAny

class SVIPPermission(object):
message="您没有访问权限!"
def has_permission(self,request,view):
if request.user.user_type >= 2:
return True
return False

频率组件自定义的模块

以一分钟访问3次为例

from rest_framework.throttling import BaseThrottle

VISIT_RECORD={}
class VisitThrottle(BaseThrottle): def __init__(self):
self.history=None def allow_request(self,request,view):
remote_addr = request.META.get('REMOTE_ADDR')
print(remote_addr)
import time
ctime=time.time() if remote_addr not in VISIT_RECORD:
VISIT_RECORD[remote_addr]=[ctime,]
return True history=VISIT_RECORD.get(remote_addr)
self.history=history while history and history[-1]<ctime-60:
history.pop() if len(history)<3:
history.insert(0,ctime)
return True
else:
return False def wait(self):
import time
ctime=time.time()
return 60-(ctime-self.history[-1])

在全局中的定制

REST_FRAMEWORK={
# 解析器组件
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
),
# 认证组件
'DEFAULT_AUTHENTICATION_CLASSES': (
'app01.utils.auth_class.UserAuth', ),
# 权限组件
'DEFAULT_PERMISSION_CLASSES': (
'app01.utils.permission_class.SVIPPermission',
),
# 频率组件
'DEFAULT_THROTTLE_CLASSES': (),
}

在局部中的定制及在视图中的使用

# 导入自定义的认证功能类
from app01.utils.auth_class import UserAuth
# 导入自定义的权限功能类
from app01.utils.permission_class import SVIPPermission
# 导入自定义的频率功能类
from app01.utils.throttle_classes import VisitThrottle from rest_framework.throttling import BaseThrottle
class VisitThrottle(BaseThrottle):
def allow_request(self,request,view):
"""
限制IP每分钟访问不能超过3次
:param request:
:param view:
:return:
"""
print(self.get_ident(request))
remote_addr = request.META.get('REMOTE_ADDR')
print("REMOTE_ADDR",remote_addr)
return False class BookView(APIView):
# 认证
# authentication_classes = [UserAuth]
# 权限
# permission_classes = [SVIPPermission]
# 频率
throttle_classes = [VisitThrottle] def get(self,request):
'''
查看所有书籍
:param request:
:return:
''' print(request.user,request.auth) book_list=Book.objects.all()
serializer=BookSerializer(book_list,many=True)
return Response(serializer.data) def post(self,request):
'''
添加一条书籍
:param request:
:return:
'''
print(request.data) serializer=BookSerializer(data=request.data,many=False) if serializer.is_valid():
serializer.save() # create操作 return Response(serializer.data)
else:
return Response(serializer.errors) class SBookView(APIView): def get(self,request,id):
edit_obj=Book.objects.get(pk=id)
serializer=BookSerializer(edit_obj,many=False)
return Response(serializer.data) def put(self,request,id):
edit_obj = Book.objects.get(pk=id)
serializer=BookSerializer(data=request.data,instance=edit_obj)
if serializer.is_valid():
serializer.save() # edit_obj.update(request.data)
return Response(serializer.data)
else:
return Response(serializer.errors) def delete(self,request,id):
edit_obj = Book.objects.get(pk=id).delete()
return Response("")

以认证为例的源码解析

//用户访问,当经过dispath时
1 def dispatch(self, request, *args, **kwargs):
self.initial(request, *args, **kwargs)
initial()是我们的解析 认证 权限 频率功能
2 在initial函数中
def initial(self, request, *args, **kwargs):
# 执行认证功能
self.perform_authentication(request)
# 执行权限功能
self.check_permissions(request)
# 执行频率功能
self.check_throttles(request)
3 我们走perform_authentication(request)认证功能
def perform_authentication(self, request):
request.user
从这里我们要从request实例中找user方法
4 我们通过request实例对象找到它的类中的user方法
def dispatch(self, request, *args, **kwargs):
request = self.initialize_request(request, *args, **kwargs)
def initialize_request(self, request, *args, **kwargs)
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
class Request(object):
def user(self):
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate()
return self._user
5 在_authenticate()中:
def _authenticate(self):
# 和解析器一样,获得[UserAuth()] 获得顺序:当前视图类下-->全局setting-->默认default
for authenticator in self.authenticators:
try:
# 执行authenticate方法进行验证,返回元组/空 或抛出一个异常
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
# 这里有个坑,如果返回元组,则直接结束_authenticate函数,不继续循环了!
return
这里如果不抛异常则进入下一个组件
												

DRF-认证 权限 频率组件的更多相关文章

  1. 实战-DRF快速写接口(认证权限频率)

    实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestframework3.13 测试工具 Postma ...

  2. restful知识点之三restframework认证-->权限-->频率

    认证.权限.频率是层层递进的关系 权限业务时认证+权限 频率业务时:认证+权限+频率 局部认证方式 from django.conf.urls import url,include from djan ...

  3. 8) drf 三大认证 认证 权限 频率

    一.三大认证功能分析 1)APIView的 dispath(self, request, *args, **kwargs) 2)dispath方法内 self.initial(request, *ar ...

  4. DRF 认证 权限 视图 频率

    认证组件 使用:写一个认证类,继承BaseAuthentication 在类中写authenticate方法,把request对象传入 能从request对象中取出用户携带的token根据token判 ...

  5. rest framework 认证 权限 频率

    认证组件 发生位置 APIview 类种的 dispatch 方法执行到 initial 方法 进行 认证组件认证 源码位置 rest_framework.authentication  源码内部需要 ...

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

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

  7. 三 drf 认证,权限,限流,过滤,排序,分页,异常处理,接口文档,集xadmin的使用

    因为接下来的功能中需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员. python manage.py createsuperuser 创建管理员以后,访问admin站点 ...

  8. Django rest_framework----认证,权限,频率组件

    认证 from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions impor ...

  9. rest-framework框架——认证、权限、频率组件

    一.rest-framework登录验证 1.models.py添加User和Token模型 class User(models.Model): name = models.CharField(max ...

随机推荐

  1. Kconfig语法简介

    背景: 上篇文章<添加自己的驱动程序到Linux内核树中>简单介绍了在Linux内核配置中添加自己的驱动选项.但是仅靠如此简单的配置有时候不能满足我们的要求. Target :hi3531 ...

  2. 10分钟学会使用Markdown绘制UML时序图

    1.1 什么是Markdown? Markdown是一种语法特别少.特别简单的标记语言,用来编写文档.用Markdown编写的文档是纯文本格式,经过编辑器的渲染,就会形成排 版优美的文档,本文就是用M ...

  3. 2020年AI、CV、NLP顶会最全时间表

    2020年AI.CV.NLP顶会最全时间表 2019-09-01 14:04:19 weixin_38753768 阅读数 40   2020 AI.CV.NLP主流会议时间表,包含会议举办的时间.地 ...

  4. C#基础--Ref与Out区别

    两者都是按地址传递的,使用后都将改变原来参数的数值. class Program { static void Main(string[] args) { int num = 1; Method(ref ...

  5. JDBC 学习复习10 编写自己的JDBC框架

    首先万分感谢狼哥 孤傲苍狼 博客,整个jdbc学习的博客资料 链接为http://www.cnblogs.com/xdp-gacl/p/4006830.html 详细代码见狼哥博客,列出我学习过程中遇 ...

  6. MVC模板页使用

    这里我们要做一个公共的模板,样式如下: 内容 ·asp.net mvc如何创建模板??1.在/Views/Shared/中右键-添加-视图 2.重命名为”HeadLayout”,勾选”创建为分部视图” ...

  7. Eclipse中如何创建一个完整的Maven-Web项目

    Maven Web项目搭建 1.首先确保本地开发环境搭建完毕(jdk,maven). 2.打开Eclipse,新建Maven项目.选择Maven Project选项. 3.将第一项:Create a ...

  8. tcp关闭连接:挥手讨论

    讨论焦点: 如果client发送FIN后,服务器端未返回完成的数据(缓存区中)还执行返回吗? 参考文档:https://download.csdn.net/download/u013547552/10 ...

  9. LVM——header

  10. 关于在window8上使用ssh命令的记录

    1.开启虚拟机以及git bash窗口,准备连接 2.在虚拟机中输入ifconfig -a查看虚拟机ip 从图中找到ip为 : inet 地址:192.168.78.133 3.输入命令: ssh r ...