Django Rest Framework框架
(1)用户url传入的token认证
urls: from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^dog/', views.DogView.as_view()), ]
models: from django.db import models class UserInfo(models.Model): username=models.CharField(max_length=32) pwd=models.CharField(max_length=128) token=models.CharField(max_length=64)
views: from rest_framework.views import APIView from rest_framework.authentication import BasicAuthentication from rest_framework import exceptions from rest_framework.request import Request from .models import *class MyAuthenTication(BasicAuthentication): def authenticate(self,request): token=request._request.GET.get('token') # token='sfsfss123kuf3j123' # 获取用户名和密码,去数据库校验 obj=UserInfo.objects.filter(token=token).first() if not obj: raise exceptions.AuthenticationFailed('用户认证失败') return (obj.username,token) def authenticate_header(self,request): pass class DogView(APIView): authentication_classes = [MyAuthenTication, ] def get(self,request,*args,**kwargs): print(request) print(request.user) ret={ 'code':10000, 'msg':'data' } return HttpResponse(json.dumps(ret),status=201) def post(self,request,*args,**kwargs): return HttpResponse('创建dog') def put(self, request, *args, **kwargs): return HttpResponse('更新dog') def delete(self, request, *args, **kwargs): return HttpResponse('删除dog')
(2)认证
使用 创建类:继承BaseAuthentication; 实现:authenticate方法 返回值: ① None,下一认证来执行。 ② raise exceptions.AuthenticationFailed('用户认证失败') # from rest_framework import exceptions
③ (元素1,元素2) # 元素1赋值给request.user; 元素2赋值给request.auth
局部使用:
from rest_framework.authentication import BaseAuthentication,BasicAuthentication
class UserInfoView(APIView):
"""
订单相关业务
"""
authentication_classes = [BasicAuthentication,]
def get(self,request,*args,**kwargs):
print(request.user)
return HttpResponse('用户信息')
全局使用:
REST_FRAMEWORK = {
# 全局使用的认证类
"DEFAULT_AUTHENTICATION_CLASSES":
['api.utils.auth.FirstAuthtication',
'api.utils.auth.Authtication', ],
# "UNAUTHENTICATED_USER":lambda :"匿名用户"
"UNAUTHENTICATED_USER":None, # 匿名,request.user = None
"UNAUTHENTICATED_TOKEN":None,# 匿名,request.auth = None
}
源码流程
dispatch
封装request
获取定义的认证类(全局/局部),通过列表生成时创建对象。
initial
perform_authentication
request.user(内部循环....)
执行CBV中的匹配到的方法
(3)权限
使用 类,必须继承:BasePermission,必须实现:has_permission方法 from rest_framework.permissions import BasePermission class SVIPPermission(BasePermission): message = "必须是SVIP才能访问" #定义无权限时页面显示的信息 def has_permission(self,request,view): if request.user.user_type != 3: return False return True 返回值 True, 有权访问 False,无权访问 局部 class UserInfoView(APIView): """ 订单相关业务(普通用户、VIP) """ permission_classes = [MyPermission1, ] def get(self,request,*args,**kwargs): return HttpResponse('用户信息') 全局 REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES":['api.utils.permission.SVIPPermission'] }
源码流程
dispatch
initial
get_permissions获取定义的权限类(全局/局部)通过列表生成时创建对象,执行has_permission方法
执行CBV中的匹配到的方法
(4)访问频率控制(节流)
自己实现: 控制访问频率 import time VISIT_RECORD = {} class VisitThrottle(object): """60s内只能访问3次""" def __init__(self): self.history = None def allow_request(self,request,view): # 1. 获取用户IP remote_addr = request.META.get('REMOTE_ADDR') 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 # return True # 表示可以继续访问 # return False # 表示访问频率太高,被限制 def wait(self): """ 还需要等多少秒才能访问 :return: """ ctime = time.time() return 60 - (ctime - self.history[-1]) class AuthView(APIView): """ 用于用户登录认证 """ authentication_classes = [] permission_classes = [] throttle_classes = [VisitThrottle,] def post(self,request,*args,**kwargs): ret = {'code':1000,'msg':None} try: user = request._request.POST.get('username') pwd = request._request.POST.get('password') obj = models.UserInfo.objects.
filter(username=user,password=pwd).first() if not obj: ret['code'] = 1001 ret['msg'] = "用户名或密码错误" # 为登录用户创建token token = md5(user) # 存在就更新,不存在就创建 models.UserToken.objects.update_or_create
(user=obj,defaults={'token':token}) ret['token'] = token except Exception as e: ret['code'] = 1002 ret['msg'] = '请求异常' return JsonResponse(ret)
内置控制频率类:
类, 继承:BaseThrottle,实现:allow_request、wait
类, 继承:SimpleRateThrottle,实现:get_cache_key、scope = "Luffy"(配置文件中的key)
from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
scope = "Luffy"
def get_cache_key(self, request, view):
return self.get_ident(request)
class UserThrottle(SimpleRateThrottle):
scope = "LuffyUser"
def get_cache_key(self, request, view):
return request.user.username
局部
class AuthView(APIView):
"""
用于用户登录认证
"""
authentication_classes = []
permission_classes = []
throttle_classes = [VisitThrottle,] # *******************
def post(self,request,*args,**kwargs):
ret = {'code':1000,'msg':None}
try:
user = request._request.POST.get('username')
pwd = request._request.POST.get('password')
obj = models.UserInfo.objects.filter(username=user,password=pwd).first()
if not obj:
ret['code'] = 1001
ret['msg'] = "用户名或密码错误"
else: # 为登录用户创建token
token = md5(user)
# 存在就更新,不存在就创建
models.UserToken.objects.update_or_create(user=obj,defaults={'token':token})
ret['token'] = token
except Exception as e:
ret['code'] = 1002
ret['msg'] = '请求异常'
return JsonResponse(ret)
全局
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_CLASSES":["api.utils.throttle.UserThrottle"],
"DEFAULT_THROTTLE_RATES":{
"Luffy":'3/m',
"LuffyUser":'10/m',
}
}
源码流程
dispatch
initial
get_throttles获取定义的节流类(全局/局部)通过列表生成时创建对象,实现类中方法
执行CBV中的匹配到的方法

浙公网安备 33010602011771号