本文主要介绍了下drf框架的token认证、授权、访问频率的使用方法。
创建数据库表
'''
用户表
'''
class User(models.Model):
name = models.CharField(max_length=32, unique=True)
password = models.CharField(max_length=64)
choices = (('1', 'Super_Admin'), ('2', 'General_Admin'), ('3', 'General_User') )
user_type = models.CharField(max_length=6, choices=choices, default='3')
'''
token表,与User表做一对一关联
'''
class Token(models.Model):
token = models.CharField(max_length=64)
user = models.OneToOneField(to='User', on_delete=models.CASCADE)
python manage.py migrate
Token认证
新建myapp/utils/auth.py文件
# 导入需要继承的基类BaseAuthentication
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from myapp import models
from rest_framework.permissions import BasePermission
# 创建认证类,继承BaseAuthentication
class MyAuth(BaseAuthentication):
# 固定写一个authenticate方法用于定义具体认证内容
def authenticate(self, request):
# 写认证逻辑代码
# 比如说假设token数据存在后端数据库中,前端发送的请求需要认证token
token = request.GET.get('token')
token_obj = models.Token.objects.filter(token=token).first()
if token_obj:
# 有值代表token校验通过
# 可以使用token_obj.user取到当前登录的user对象
# 这里需要返回2个数据,rest framework内部将这俩字段赋值给request,以便后续使用
return token_obj.user, token_obj
else:
raise AuthenticationFailed('未授权')
局部认证,在class级别生效
访问提示未授权
添加用户和token
输入正确的token后可以正常访问了
全局认证
实际场景下通常使用全局认证对少量路由局部授权,在settings.py文件里添加全局变量
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["myapp.utils.auth.MyAuth", ],
}
再测一下结果一样。
全局认证–局部授权
全局认证已设置,视图中的所有类都会进行设置值的认证,这显然是不符合实际的,因为有些视图不能设置认证,比如注册,登录
所以需要局部对认证进行认证禁用,方法:
在局部认证的 视图类 位置添加下述代码,完成局部禁用
authentication_classes = []
用户登录接口
from uuid import uuid4
from django.core.exceptions import ObjectDoesNotExist
class Login(APIView):
# 允许匿名访问
authentication_classes = []
def post(self, request):
response = {'code': 100, 'msg': '登录成功'}
name = request.data.get('name')
password = request.data.get('password')
try:
# 使用get方法,get方法只能取一条数据,如果是多条或者取不到,则会抛异常
user = User.objects.filter(name=name, password=password).get()
# 通过try方法捕获异常,如果走到这里说明没有异常,get方法取到用户对象,用户登录成功
# 登录成功需要进行token表的数据保存(这里先假设token是保存在服务端数据库中)
# 生成一个卫衣的id,使用uuid模块
token = uuid4()
# token如果在用户数据库中存在则更新,没有的话则创建
# 使用update_or_create方法
Token.objects.update_or_create(user=user, defaults={'token': token})
# 将token放入返回的字典中
response['token'] = token
# 捕获一个特别的异常,user对象如果不存在则会走此处
except ObjectDoesNotExist as e:
response['code'] = 101
response['msg'] = '用户名或密码错误'
# 捕获其它异常
except Exception as e:
print(e)
response['code'] = 102
response['msg'] = '未知错误'
# 返回前端数据
return Response(response)
在myapp/urls.py里添加路由
path(‘login’, Login.as_view()),
权限
myapp/utils/auth.py添加权限类
# 创建认证类,BasePermission
class MyPermission(BasePermission):
message = '权限不足,无法查看'
# 固定写一个has_permission方法用于定义具体权限内容
def has_permission(self, request, view):
# #因为权限在认证之后执行的,所有能取到reuqest.user,
print(request.user.user_type)
if request.user.user_type == '1':
return True
else:
return False
settings.py添加全局配置
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["myapp.utils.auth.MyAuth", ],
"DEFAULT_PERMISSION_CLASSES": ["myapp.utils.auth.MyPermission", ],
}
局部禁用权限控制,在class级别生效
class Login(APIView):
# 允许匿名访问
authentication_classes = []
# 取消权限控制
permission_classes = []
......
......
频率限速
myapp/utils/auth.py添加限速类
from rest_framework.throttling import SimpleRateThrottle
class Throttle(SimpleRateThrottle):
scope = 'info'
def get_cache_key(self, request, view):
return self.get_ident(request)
在settings.py中配置:
REST_FRAMEWORK = {
# 一分钟内只能访问6次
'DEFAULT_THROTTLE_RATES': {'info': '6/m'}
}
局部使用
from myapp.utils.auth import Throttle
class MusicList(APIView):
authentication_classes = []
permission_classes = []
throttle_classes = [Throttle, ]
参考:
https://www.cnblogs.com/suguangti/p/11130015.html#2249158257