REST framwork之认证,权限与频率
认证组件
局部视图认证
在app01.service.auth.py:
class Authentication(BaseAuthentication): def authenticate(self,request):
token=request._request.GET.get("token")
token_obj=UserToken.objects.filter(token=token).first()
if not token_obj:
raise exceptions.AuthenticationFailed("验证失败!")
return (token_obj.user,token_obj)
在views.py:
def get_random_str(user):
import hashlib,time
ctime=str(time.time()) md5=hashlib.md5(bytes(user,encoding="utf8"))
md5.update(bytes(ctime,encoding="utf8")) return md5.hexdigest() from app01.service.auth import * from django.http import JsonResponse
class LoginViewSet(APIView):
authentication_classes = [Authentication,]
def post(self,request,*args,**kwargs):
res={"code":1000,"msg":None}
try:
user=request._request.POST.get("user")
pwd=request._request.POST.get("pwd")
user_obj=UserInfo.objects.filter(user=user,pwd=pwd).first()
print(user,pwd,user_obj)
if not user_obj:
res["code"]=1001
res["msg"]="用户名或者密码错误"
else:
token=get_random_str(user)
UserToken.objects.update_or_create(user=user_obj,defaults={"token":token})
res["token"]=token except Exception as e:
res["code"]=1002
res["msg"]=e return JsonResponse(res,json_dumps_params={"ensure_ascii":False})
全局视图认证组件
settings.py配置如下:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}
权限组件
局部视图权限
在app01.service.permissions.py中:
from rest_framework.permissions import BasePermission
class SVIPPermission(BasePermission):
message="SVIP才能访问!"
def has_permission(self, request, view):
if request.user.user_type==3:
return True
return False
在views.py:
from app01.service.permissions import * class BookViewSet(generics.ListCreateAPIView):
permission_classes = [SVIPPermission,]
queryset = Book.objects.all()
serializer_class = BookSerializers
全局视图权限
settings.py配置如下:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
"DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",]
}
throttle(访问频率)组件
局部视图throttle
在app01.service.throttles.py中:
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])
在views.py中:
from app01.service.throttles import * class BookViewSet(generics.ListCreateAPIView):
throttle_classes = [VisitThrottle,]
queryset = Book.objects.all()
serializer_class = BookSerializers
全局视图throttle
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
"DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",],
"DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",]
}
内置throttle类
在app01.service.throttles.py修改为:
class VisitThrottle(SimpleRateThrottle): scope="visit_rate"
def get_cache_key(self, request, view): return self.get_ident(request)
settings.py设置:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
"DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",],
"DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",],
"DEFAULT_THROTTLE_RATES":{
"visit_rate":"5/m",
}
}
根据访问频率组件Throttle 设计一个程序:
每分钟同一个IP只能访问十次
from django.db import models # Create your models here. class Userinfo(models.Model):
name=models.CharField(max_length=32,verbose_name='用户名')
pwd=models.CharField(max_length=32,verbose_name='密码')
token=models.CharField(max_length=64,null=True) def __str__(self):
return self.name
models
from django.shortcuts import render # Create your views here. import time from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.throttling import BaseThrottle
from rest_framework import exceptions # Create your views here. AllOW = {} class MyThrottle(BaseThrottle):
'''
限制每分钟访问10次
'''
ip = '127.0.0.1'
def allow_request(self, request, view):
ctime = time.time() # 当前时间。
ip = self.ip # IP。
if ip not in AllOW: # 如果IP不在ALLOW里面。
AllOW[ip] = [ctime, ] # 为IP设置一个当前时间。
else:
time_list = AllOW[ip] # IP对应的访问时间。
while True:
if not time_list: # 这里加判断是为了防止,在time_list中没有值的时候会报错。
break
if ctime - 60 > time_list[-1]: # 当当前的时间减去60,大于最初的时间。
time_list.pop() # 自动去掉最初的一条记录。
else:
break
if len(AllOW[ip]) > 9: # 如果一分钟内,IP的访问次数超过10次。
return False
AllOW[ip].insert(0, ctime)
return True def wait(self):
ip = self.ip
ctime = time.time()
first_in_time = AllOW[ip][-1]
wt = 60 - (ctime - first_in_time) # 等待时间,当前时间减去最后一次的时间得到的一个数,然后再使用60秒减去这个数。
return wt class Limitview(APIView):
throttle_classes = [MyThrottle,] # 请求频率的设置为MyThrottle def get(self, request):
return Response('欢迎进入python的世界!!!') def throttled(self, request, wait):
class InnerThrottled(exceptions.Throttled):
default_detail = '您的请求已被限制.'
extra_detail_singular = 'Expected available in {wait} second.'
extra_detail_plural = '请耐心等待{wait}秒' raise InnerThrottled(wait)
view.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^Limitview/',views.Limitview.as_view())
]
urls
REST_FRAMEWORK = {
'UNAUTHENTICATED_USER': None,
'UNAUTHENTICATED_TOKEN': None,
"DEFAULT_AUTHENTICATION_CLASSES": [
# "app01.utils.MyAuthentication",
# "app02.utils.MyAuthentication",
],
"DEFAULT_PERMISSION_CLASSES":[
# "app02.utils.MyPermission",
# "app02.utils.AdminPermission",
],
"DEFAULT_THROTTLE_RATES":{
'tiga':'10/m',
}
}
settings
那么我们还可以把认证,权限与频率组合起来进行一个访问频率限制:
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.throttling import SimpleRateThrottle
from rest_framework import exceptions from app01 import models # Create your views here.
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
token=request.query_params.get(‘token‘)
user=models.Userinfo.objects.filter(token=token).first()
if user:
return (user.name,user)
return None class UserPermission(BasePermission):
message=‘登录用户才可以访问‘
def has_permission(self, request, view):
if request.user:
return True
return False
class AdminPermission(BasePermission):
message=‘管理员才能访问‘
def has_permission(self, request, view):
if request.user ==‘ctz‘:
return True
return False class AnnoThrottle(SimpleRateThrottle):
scope = ‘anno‘
def get_cache_key(self, request, view):
#如果是匿名用户则执行
if not request.user:
return self.get_ident(request)
#如果不是匿名用户则让他执行
return None class UserThrottle(SimpleRateThrottle):
scope = ‘user‘ def get_cache_key(self, request, view):
#当前用户登陆了,并且当前用户不是管理员
if request.user and request.user!=‘ctz‘:
return self.get_ident(request)
#如果是匿名用户和管理员 则让他继续执行
return None class AdminThrottle(SimpleRateThrottle):
scope = ‘admin‘ def get_cache_key(self, request, view):
#如果是管理员
if request.user==‘ctz‘:
return self.get_ident(request)
#不是管理员
return None class IndexView(APIView):
‘‘‘
要求,所有用户都能访问,匿名用户5/m,普通用户10/m,管理员不限
‘‘‘
authentication_classes = [MyAuthentication,]
permission_classes = []
throttle_classes = [AnnoThrottle,UserThrottle,AdminThrottle]
def get(self,request):
return Response(‘首页‘) def throttled(self, request, wait):
class UserInnerThrottled(exceptions.Throttled):
default_detail = ‘请求被限制.‘
extra_detail_singular = ‘Expected available in {wait} second.‘
extra_detail_plural = ‘还需要再等待{wait}秒‘
raise UserInnerThrottled(wait) class UserView(APIView):
‘‘‘
要求:登录用户能访问,普通用户10/m,管理员20/m
‘‘‘
authentication_classes = [MyAuthentication,]
permission_classes = [UserPermission,]
throttle_classes = [UserThrottle,AdminThrottle]
def get(self,request):
return Response(‘用户界面‘) def permission_denied(self, request, message=None):
"""
If request is not permitted, determine what kind of exception to raise.
""" if request.authenticators and not request.successful_authenticator:
raise exceptions.NotAuthenticated(‘无权访问‘)
raise exceptions.PermissionDenied(detail=message) def throttled(self, request, wait):
class UserInnerThrottled(exceptions.Throttled):
default_detail = ‘请求被限制.‘
extra_detail_singular = ‘Expected available in {wait} second.‘
extra_detail_plural = ‘还需要再等待{wait}秒‘
raise UserInnerThrottled(wait) class ManageView(APIView):
‘‘‘
要求:只有管理园能访问,5/m
‘‘‘
authentication_classes = [MyAuthentication,]
permission_classes = [AdminPermission,]
throttle_classes = [AdminThrottle]
def get(self,request):
return Response(‘管理员界面‘) def permission_denied(self, request, message=None):
"""
If request is not permitted, determine what kind of exception to raise.
""" if request.authenticators and not request.successful_authenticator:
raise exceptions.NotAuthenticated(‘无权访问‘)
raise exceptions.PermissionDenied(detail=message) def throttled(self, request, wait):
class UserInnerThrottled(exceptions.Throttled):
default_detail = ‘请求被限制.‘
extra_detail_singular = ‘Expected available in {wait} second.‘
extra_detail_plural = ‘还需要再等待{wait}秒‘
raise UserInnerThrottled(wait)
view.py
from django.db import models # Create your models here.
class Userinfo(models.Model):
name=models.CharField(max_length=32,verbose_name=‘用户名‘)
pwd=models.CharField(max_length=32,verbose_name=‘密码‘)
token=models.CharField(max_length=64,null=True) def __str__(self):
return self.name
models
REST_FRAMEWORK = {
‘UNAUTHENTICATED_USER‘: None,
‘UNAUTHENTICATED_TOKEN‘: None,
"DEFAULT_AUTHENTICATION_CLASSES": [
# "app01.utils.MyAuthentication",
"app02.utils.MyAuthentication",
],
"DEFAULT_PERMISSION_CLASSES":[
"app02.utils.MyPermission",
"app02.utils.AdminPermission",
],
"DEFAULT_THROTTLE_RATES":{
‘tiga‘:‘10/m‘,
‘anno‘:‘5/m‘,
‘user‘:‘10/m‘,
‘admin‘:‘20/m‘,
}
}
settings
url(r‘^index/‘, views.IndexView.as_view()),
url(r‘^user/‘, views.UserView.as_view()),
url(r‘^manage/‘, views.ManageView.as_view()),
urls
REST framwork之认证,权限与频率的更多相关文章
- DRF 认证 权限 视图 频率
认证组件 使用:写一个认证类,继承BaseAuthentication 在类中写authenticate方法,把request对象传入 能从request对象中取出用户携带的token根据token判 ...
- restful知识点之三restframework认证-->权限-->频率
认证.权限.频率是层层递进的关系 权限业务时认证+权限 频率业务时:认证+权限+频率 局部认证方式 from django.conf.urls import url,include from djan ...
- rest-framework框架——认证、权限、频率组件
一.rest-framework登录验证 1.models.py添加User和Token模型 class User(models.Model): name = models.CharField(max ...
- restful(3):认证、权限、频率 & 解析器、路由控制、分页、渲染器、版本
models.py中: class UserInfo(models.Model): name = models.CharField(max_length=32) psw = models.CharFi ...
- Rest_Framework之认证、权限、频率组件源码剖析
一:使用RestFramwork,定义一个视图 from rest_framework.viewsets import ModelViewSet class BookView(ModelViewSet ...
- 实战-DRF快速写接口(认证权限频率)
实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestframework3.13 测试工具 Postma ...
- django-rest-framework 基础三 认证、权限和频率
django-rest-framework 基础三 认证.权限和频率 目录 django-rest-framework 基础三 认证.权限和频率 1. 认证 1.1 登录接口 1.2 认证 2. 权限 ...
- DRF 权限和频率
Django Rest Framework 权限组件 DRF的权限 权限组件源码解析 我们之前说过了DRF的版本和认证~也知道了权限和频率跟版本认证都是在initial方法里初始化的~~ 其实我们版本 ...
- drf6 权限和频率控制组件
对某件事情决策的范围和程度,我们叫做权限,权限是我们在项目开发中非常常用到的. DRF框架给我们提供的权限组件 权限组件 之前DRF的版本和认证,知道了权限和频率跟版本认证都是在initial方法里初 ...
- DRF的权限和频率
DRF的权限 权限组件源码 权限和频率以及版本认证都是在initial方法里初始化的 我们的权限类一定要有has_permission方法~否则就会抛出异常~~这也是框架给我提供的钩子~~ 在rest ...
随机推荐
- JDK动态代理实例
最近看<深入浅出MyBatis技术原理与实战>这本书时,里面讲到Mapper接口的内部实现是通过JDK动态代理生成实现类,联想到之前看<SPRING技术内幕>这本书里也常常提到 ...
- TP5 中引入第三方类库
通过了解tp5的目录结构,我们知道其中有两个目录是纺织扩展类库文件的. extend是放置自定义或者其他类文件的. vendor目录是放置composer类库文件的. 当我们的第三方类库文件是下载的, ...
- 服务网关Zuul
路由+过滤器 = Zuul 核心是一系列的过滤器 Zuul的四种过滤器API 前置(PRE) 后置(POST) 路由(Route) 错误(Error) Zuul组织架构图 二.Zuul的使用 1 创建 ...
- sparkSQL以JDBC为数据源
一.环境准备 安装oracle后,创建测试表.数据: create table test ( username varchar2(32) primary key , password varchar2 ...
- 阅读 ‘External Memory PHY Interface (ALTMEMPHY)’笔记
阅读 ‘External Memory PHY Interface (ALTMEMPHY)’笔记 1.PLL reference clock frequency 此处控制器输入时钟设置为100MHz, ...
- javascript 对象的原型
往往定义一个函数时,函数内部有关键字this时,就把这个函数当成对象,this相当于python中的self.都是对象中用到的,代表对象本身. js不像python,在函数内部定义的子函数,在每次创建 ...
- [置顶] Web用户的身份验证及WebApi权限验证流程的设计和实现 (不是Token驗證!!!不是Token驗證!!!都是基於用户身份的票据信息驗證!!!)
转发 http://blog.csdn.net/besley/article/details/8516894 不是Token驗證!!!不是Token驗證!!!都是基於用户身份的票据信息驗證!!! [ ...
- line-height的理解
font-size:0清除display:inline-block元素换行符间隙,比如两个img标签之间有换行符 行内元素的高度是由其行高决定的. Div或者其他元素内的图片,底部会有间隙,原因是图片 ...
- java线程大全一讲通
Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...
- Linux bash笔记
关于bash脚本,一般开头都加#!/bin/bash,表示以bash来作为脚本解释器:如果不加的话,就会默认当前用户登陆的shell为脚本解释器(很多情况下为sh,sh与bash不同,有可能导致脚本无 ...