Django Rest Framework-认证、限制、节流
认证、权限、节流
身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制。然后 权限 和 限制 组件决定是否拒绝这个请求。
简单来说就是:
认证确定了你是谁 (认证)
权限确定你能不能访问某个接口 (权限)
节流确定你访问某个接口的频率 (节流)
认证
示例:
models
from django.db import models # Create your models here. class User(models.Model): level_choices = ( (1, '普通用户'), (2, 'VIP'), (3, 'SVIP'), ) level = models.IntegerField(choices=level_choices) username = models.CharField(max_length=32, unique=True) password = models.CharField(max_length=64) def __str__(self): return self.username class UserToken(models.Model): user = models.OneToOneField(to='User', on_delete=models.CASCADE) token = models.CharField(max_length=64) def __str__(self): return self.user.get_level_display()
url
from django.urls import path from app01 import views urlpatterns = [ path('api/v1/auth', views.AuthView.as_view()), ]
view
from django.http import JsonResponse from rest_framework.views import APIView from rest_framework import exceptions from app01 import models from app01.utils.auth import UserAuth import time import hashlib def get_token(user): m = hashlib.md5(bytes(user, encoding='utf-8')) ctime = str(time.time()) m.update(bytes(ctime, encoding='utf-8')) return m.hexdigest() class AuthView(APIView): """ 用于验证登录 """ authentication_classes = [] def post(self, request, *args, **kwargs): # 返回的状态和信息 data = {'code': 1000, } try: username = request._request.POST.get('username') password = request._request.POST.get('password') user = models.User.objects.filter(username=username, password=password).first() if not user: data['code'] = 1001 data['error'] = '用户名或密码错误' return JsonResponse(data) token = get_token(username) models.UserToken.objects.update_or_create(user=user, defaults={'token': token}) data['token'] = token data['msg'] = '登录成功' return JsonResponse(data) except Exception as e: data['code'] = 1002 data['error'] = '请求出错' return JsonResponse(data)
UserAuth
from app01 import models from rest_framework import exceptions from rest_framework.authentication import BaseAuthentication class UserAuth(BaseAuthentication): """ 用户认证是否登录 """ def authenticate(self, request): try: token = request._request.GET.get('token') user_token = models.UserToken.objects.filter(token=token).first() if not user_token: raise exceptions.AuthenticationFailed('用户未登录') return user_token.user, token except: raise exceptions.AuthenticationFailed('请求出错')
局部配置
# 在视图函数中配置上,可配一个或多个 authentication_classes = [UserAuth]
全局配置
REST_FRAMEWORK={ 'DEFAULT_AUTHENTICATION_CLASSES':['app01.utils.auth.UserAuth'], # 认证不通过或认证类通过认证但无返回值时,设置的用户和token 默认为AnonymousUser和None. UNAUTHENTICATED_USER:"匿名用户", UNAUTHENTICATED_TOKEN:None }
权限
view
from django.http import JsonResponse from rest_framework.views import APIView from app01.utils.permission import SVIPPermission from app01 import models class OrderView(APIView): # authentication_classes = [UserAuth,] permission_classes = [SVIPPermission, ] throttle_classes = [IPThrottle, ] def get(self, request, *args, **kwargs): self.dispatch() ret = {'code': 1000, 'msg': None, 'data': None} try: ret['data'] = '订单信息' ret['msg'] = '已登录' except: ret['code'] = 1001 ret['msg'] = '未登录' return JsonResponse(ret)
permission
from rest_framework.permissions import BasePermission class SVIPPermission(BasePermission): message = '无权限访问' def has_permission(self, request, view): if request.user.level == 3: return True else: return False
节流
基于用户IP限制访问频率
urls.py
views.pyb. 基于用户IP显示访问频率(利于Django缓存)
settings.py
urls.py
views.pyc. view中限制请求频率
settings.py
urls.py
views.pyd. 匿名时用IP限制+登录时用Token限制
settings.py
urls.py
views.pye. 全局使用
settings

浙公网安备 33010602011771号