python token 访问控制限制_DRF之访问权限控制和访问频率控制(节流)

e1903a560fa5fc9e1a2b4f507b9c8581.png

权限控制

前言

用户验证用户权限,根据不同访问权限控制对不同内容的访问。

建议了解视图、token验证的内容。

使用流程

自定义访问权限类,继承BasePermission,重写has_permission()方法,如果权限通过,就返回True,不通过就返回False。has_permission()方法接受两个参数,分别是request和view,也就是视图类的实例化本身。

4f4e0b3a8367e22a81e85c704e12bdd8.png

配置。

局部配置:

permission_classes = [MyUserPermission]

全局配置:

REST_FRAMEWORK={

"DEFAULT_PERMISSION_CLASSES": ["libs.MyAuth.UserPermission",],

}

示例

class SVIPPermission(BasePermission): # 推荐继承BasePermission类

# message = "You do not have permission to perform this action."#默认值

message = "无此权限!!!"

def has_permission(self, request, view):

if request.user.user_type == 3:

return False # False为没权限

# view.queryset = # 可以使用这种方式控制视图中要处理的数据(根据不同权限)

return True # True为有权限

源码分析

进入dispatch函数,查看initial方法(执行三大验证)中的check_permissions方法:

45cdea9845b9fa59ff99cc0e83510da2.png

self.check_permissions(request)将会根据request中的用户内容进行权限控制。

569eedcbc1412c0888719e0509153121.png

51e5ddcedb7ee4c73f9944ab8a4c394f.png

a2f6725182739d015f68b4df427e1e5f.png

由上可知,permission_classes要么读取配置文件中的DEFAULT_PERMISSION_CLASSES(全局),要么就在视图类中直接对permission_classes赋值(局部)。

节流限制

前言

控制网站访问频率。

使用流程

自定义限制类,继承BaseThrottle。

指定从配置文件中要读取的scope(key),形式为scope="key"

全局配置:

REST_FRAMEWORK = {

"DEFAULT_THROTTLE_CLASSES": [

"rest_framework.throttling.AnonRateThrottle",

"rest_framework.throttling.UserRateThrottle"

],

"DEFAULT_THROTTLE_RATES": {

"anon": "100/day",

"user": "1000/day"

}

}

局部配置:

throttle_classes = [UserRateThrottle]

就比如UserRateThrottle,继承了SimpleRateThrottle,指定了它所限制的scope,重写了get_cache_key方法。

b159779e65d878f747dfec93797e96e4.png

源码分析

在APIView的initial方法中,三大验证还剩下最后一个没有分析,那就是访问频率验证,如下图:

31e4f00c212426f90b4ab489c53cba61.png

接下来让我们查看check_throttles,可以看到,验证访问频率的时候,调用的方法为频率验证类的allow_request方法。

f7f2d272a948e231ece06275e4ea2418.png

其中get_throttles用的还是老套路:

ed1cb162abec8c3dcdb077d6e705cf9b.png

示例

自定义一个频率限制类:

from rest_framework.throttling import BaseThrottle

import time

# 存放访问记录(一般放数据库或者缓存中)

VISIT_RECORD = {}

class VisitThrottle(BaseThrottle):

def __init__(self):

self.history = None

def allow_request(self, request, view):

# 1. 获取用户ip

remote_addr = request.META.get("REMOTE_ADDR")

# 2. 添加到访问记录中

ctime = time.time()

# 当VISIT_RECORD中没有这个记录,可以直接访问,添加一个记录

if remote_addr not in VISIT_RECORD:

VISIT_RECORD[remote_addr] = [ctime, ]

return True

history = VISIT_RECORD.get(remote_addr)

self.history = history

# 拿到最后历史记录里面的最后一个时间,如果最后一个时间小于当前时间-60(一分钟之前的记录)

while history and history[-1] < ctime - 60:

history.pop()

if len(history) < 3:# 允许

history.insert(0, ctime)

return True

return False # False表示访问频率太高被限制

def wait(self):

"""

还需要等多少秒可以访问

:return:

"""

ctime = time.time()

return 60 - (ctime - self.history[-1])

注意:官方内置的 SimpleRateThrottle 类中对scope的处理值得一看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值