7、认证、权限、频率
一、drf之认证功能类
用户登录后才能访问接口
1、表准备
# 用户表
class User(models.Model):
name = models.CharField(max_length=16) # 用户名
password = models.CharField(max_length=32) # 密码
# 用户状态表
class UserToken(models.Model):
user = models.OneToOneField(to=User, on_delete=models.CASCADE) # 一对一表关系外键
token = models.CharField(max_length=32)
2、登录功能
# 如果全局使用了认证类,登录接口需要局部禁用掉
class LoginView(ViewSet):
# 不使用任何认证类(全局配置认证类时,登录功能也要认证,这样不合理,所以这里需要单独禁用认证类)
authentication_classes = []
@action(methods=['POST'], detail=False)
def login(self, request):
name = request.data.get('name')
password = request.data.get('password')
user = User.objects.filter(name=name, password=password).first()
if user:
# 生成一个随机字符串
# 通过伪随机数生成一个永不重复的字符串
token = str(uuid.uuid4())
# 把随机字符串存入表,UserToken表,如果存在,就更新token,如果不存在,就新增
UserToken.objects.update_or_create(defaults={'token': token}, user=user)
return Response({'code': 100, 'msg': '登录成功', 'token': token})
else:
return Response({'code': 101, 'msg': '用户名或密码错误'})
3、认证类编写
# 自定义认证类,要继承BaseAuthentication,重写authenticate,如果认证通过,返回两个值,如果认证失败,抛认证失败的异常,这里我就在应用下新建了一个auth.py文件
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from .models import UserToken
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
# 校验用户是否登录:看它有没有带token来,以及token是不是合法的(是不是我给的)
token = request.GET.get('token')
# 校验token是否合法(根据token去库中查询是否存在,如果存在,就是登陆了,放行)
user_token = UserToken.objects.filter(token=token).first()
if user_token:
# 带的token是有效的
# user_token.user当前登录用户
return user_token.user, token
else:
raise AuthenticationFailed('token不合法或没有迭代token')
4、认证类的使用
# 局部使用(在视图类中加入)
# 认证类的局部配置
from app01.auth import LoginAuth
class PublishView(ModelViewSet):
# 局部配置,把认证类放入中括号里
authentication_classes = [LoginAuth,]
# 全局使用(在配置文件加入)
# 认证类的全局配置
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.auth.LoginAuth", ]
}
二、drf之权限类
权限:可以限制用户访问的接口,比如说一个网站有两种用户,管理员和普通用户,那么管理员用户肯定拥有一些普通用户没有的权限。
1、权限类编写
# 继承BasePermission,重写has_permission,如果有权限,就返回True,没有权限就返回False
from rest_framework.permissions import BasePermission
class PermissionUser(BasePermission):
def has_permission(self, request, view):
# 如果有权限,返回True
if request.user.user_type == 1:
return True # 超级用户允许访问
else:
return False
2、局部和全局使用
# 认证类的局部配置
from app01.auth import LoginAuth
class PubView(ModelViewSet):
# 权限类:publish的5个接口,必须超级用户才能访问
permission_classes = [PermissionUser]
# 全局使用
REST_FRAMEWORK={
"DEFAULT_PERMISSION_CLASSES":["app01.auth.PermissionUser",]
}
三、drf之频率类
1、频率限制
限制用户的访问次数:根据用户ip地址限制
# 访问者IP地址
request.META.get('REMOTE_ADDR')
# 频率类的使用
'''
1、写一个类,继承SimpleRateThrottle,重写get_cache_key,返回ip就以ip限制
2、在类中写一个类属性:scope = 'ip_m_3'
'''
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
class MyThrotting(SimpleRateThrottle):
# 类属性scope,名字随便取,在配置文件中配置雅阁与之对应的值
scope = 'ip_m_3'
def get_cache_key(self, request, view):
# return了什么就以什么作为限制
return request.META.get('REMOTE_ADDR') # return的是一个ip地址
# 3 在settings.py中写
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
# key值是频率类中scop字段对应的值,value是访问次数限制
'ip_m_3': '3/m',
}
}
2、局部和全局使用
# 1、局部使用-配置在视图类中
class IndexView(APIView):
throttle_classes = [MyThrotting, ] # 使用
def get(self, request):
return Response('ok')
# 2、全局使用-配置在settings.py中
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': ['app01.auth.MyThrotting',],
}
'''
如果要禁用某个视图类的频率类,就和局部使用差不多,只需要括号内导入的频率类删掉,成为一个空列表就可以了
throttle_classes = []
'''
额外小知识:可以拿到访问者的ip地址
class MyThrotting(SimpleRateThrottle): scope = 'ip_m_3' def get_cache_key(self, request, view): return self.get_ident(request) #返回访问者的ip:BaseThrottle的访问

浙公网安备 33010602011771号