认证,权限
认证和权限一般都是一块使用的他的意识是重字面上理解很简答他的意识就是!访问一些接口的内容需经过认证才可以访问那么权限呢就是相当于我们普通用户和VIP用户了这个就是简单的认证,权限的简单理解了!那么至于这么去实现这个功能!下面代码有详细的解释!
#这里就是我们要导入一些我们要用到的包
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from authapp.models import UserToken
class MyOrderAuthentication(BaseAuthentication):
"""
在这里实现认证的逻辑
"""
def authenticate(self, request):
#这里就是获取到我们的token
#至于token哪里来的就是经过登录后随机产生出一个字符串
token = request._request.GET.get('token')
# 获取到token之后,需要在数据库中查找token
obj = UserToken.objects.filter(token=token).first()
if not obj:
# 没有通过认证
raise AuthenticationFailed('认证失败')
# 返回元组( user, auth )
return (obj.user, obj)
#那么他返回的是个什么东西呢obj.user返回的就是我们用户,
#那么这个obj呢就是我的这个token了
下面我们说一下权限的具体实现功能
#日常导包我们就不说了
from rest_framework.permissions import BasePermission
class MyOrderPermission(BasePermission):
"""自定义权限认证的类,必须要实现has_permission方法"""
message = '你不是超级用户,没有权限访问'
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
返回True表示有权限访问,返回False表示没有权限访问
"""
#这个判断他会去获取我们的之前在注册的时候输入的这个用
# 户类型(1,‘普通用户’,2’VIP用户‘)他拿到后会去执行
#下面的判断
if request.user.user_type != 2:
return False
return True
#如多判断成立的话他就会return False 反之就是return True
#就可以拿到我们需要的数据了!
节流
上面呢我们说道了认证和权限现在我们来说节流想!
节流重字面上理解节约的意思是吧!那么我们这个DRF上的节流是什么意识它的意识也很简单就是通俗的来说就是反爬虫的一些手段那么至于这么去实现这个功能呢!下面的代码会有详细的注释!
class VisitThrottle(BaseThrottle):
def __init__(self):
self.history = None
def allow_request(self,request,view):
"""实现节流的逻辑"""
ip_address = self.get_ident(request)
ctime = time.time()
if ip_address not in VISIT_RECORD:
#第一次访问的时候将访问的时间存储在字典中(ip地址为Key,访问的时间为value值)
VISIT_RECORD[ip_address] = [ctime,]
#
#第二次访问的时候取出访问的历史记录
history = VISIT_RECORD[ip_address]
# 基于用户的节流
username = request.user.username
if username not in VISIT_RECORD:
VISIT_RECORD[username] = [ctime, ]
history = VISIT_RECORD[username]
self.history = history
while history and history[-1] < ctime - 10:
"""如果访问的时间记录超过60秒,就把超过60秒的时间记录移除"""
history.pop()
if len(history) < 6:
history.insert(0,ctime)
return True
return False
def wait(self):
"""一旦用户访问次数到达阀值,显示用户需要等待的时间"""
ctime = time.time()
#09:54:30 09:54:28
return 10 - (ctime - self.history[-1])
class VisitThrottle(SimpleRateThrottle):
#没有登录用户,每分钟访问10次
scope = 'unlogin'
def get_cache_key(self, request, view):
return self.get_ident(request)
版本
在字面上来看就是一代一代升级了那么版本在这里面的意识就是我们每开发一条api他都是有他的版本已好区分!
class ParmasVersion(object):
def determine_version(self, request, *args, **kwargs):
version = request.query_params.get('version')
return version
#这下面就是一些版本设置的问题
'VERSION_PARAM':'version',
#如果没有版本默认为v1
'DEFAULT_VERSION':'v1',
#版本规定只能有v1, or v2
'ALLOWED_VERSIONS':['v1','v2'],
versioning_class = URLPathVersioning
url 规则 (?P < version > [v1 | v2] +)
print(request.versioning_scheme.reverse(viewname='api:user', request=request)) 这里可以通过request.versioning_scheme.reverse 进行url 反向解析
>> http: // 127.0.0.1: 8000 / api / v2 / user /
解析器
1 请求头中 Content-Type : application/x-www-form-urlencoded,
2 数据格式: name=alex&age=18
request.POST 中才有值
比如 form 表单提交 满足 1,2
ajax 提交的时候也是默认 1,2 条件
当然可以定义 ajax 发送的请求头和数据格式:
headers:{'Content-Type':'application/json'}
data:JSONstringfy({name:'aaa',age:12})
这时候 后台 request.POST 中不再有数据
可以从 request.BODY 中获取数据
注意:只有使用 request.data的时候,parser对象才调用
#如果客户端的Content-Type的值和 application/json 匹配:JSONParser处理数据
#如果客户端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser处理数据
1 获取用户的请求
2 获取用户的请求体
3 根据用户的请求头 和 parser_classes 中支持的 parser 进行比较
4 parser对象 去请求
5 request.data