认证
认证组件
认证有什么用:
一些接口,想限制登录的后才能访问,没登录不能访问
做登录认证,限制如果没登录,不允许访问该接口
drf中认证类如何使用:
1、写一个类,继承BaseAuthentication
2、类中重写:authenticate方法
3、在authenticate完成登录认证,如果登录了,返回两个值,第一个值是user_token.user,第二个是token,如果能拿的出就是登录了,拿不出就是未登录,抛异常
4、在视图类中配置使用
class BookView(ViewSet):
authentication_classes = [LoginAuth]
认证小结:
1、认证类的使用:
配置在视图类上:局部使用
配置文件中配置:全局使用——所有接口必须登录后才能使用(值得注意的是,这里的全局使用也包含了登录本身,所以要对登录进行局部禁用)
全局使用(配置文件中): REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'app01.auth.LoginAuth' ], }
局部禁用:
class UserView(ViewSet): authentication_classes = []
2、写的认证类:要重写authenticate方法,必须返回两个参数:
当前登录用户返回:第一个参数是user_token.user,第二个参数是用户的 token
在视图类中显示的是:request.user(认证类的第一个参数),request.auth认证类返回的第二个参数
3、如果认证失败就抛异常
AuthenticationFailed,会被def捕获处理,不会报错到前端
4、前端传入的token,如何取:
后端定的,我们项目是从请求地址中取,还可以从请求头或者请求体中取
5、update_or_create方法:
update_or_create(self, defaults=None, **kwargs)
如果 **kwargs有值,defaults就是更新
如果**kwargs没有值,defaults就是新增
登录认证例子:
auth:
from.models import UserToken from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed class Loginauth(BaseAuthentication): def authenticate(self, request): #从请求地址中输入token token = request.query_params.get('token') #如果当前token和数据库中的token匹配 res = UserToken.objects.filter(token=token).first() if res: return res.user,token else: raise AuthenticationFailed('还未登录')
views:
#登录功能 from rest_framework.viewsets import ViewSet from .models import User,UserToken from rest_framework.decorators import action import uuid class LoginView(ViewSet): @action(methods=['POST'],detail=False) def logini(self,request): name = request.data.get('name') password = request.data.get('password') user = User.objects.filter(name=name,password=password).first() if user: #第一种方法 # #先生成token token =str(uuid.uuid4()) # #查找是否有token,有就修改,没有添加 # token_find = UserToken.objects.filter(user=user).first() # if token_find: # token_find.token = token # token_find.save() # else: # UserToken.objects.create(user=user,token=token) #第二种方法 UserToken.objects.update_or_create(defaults={'token':token},user=user) #如果用户存在就修改token,如果不存在就加入 return Response({'code':200,'msg':'登录成功','token':token,'name':user.name}) else: return Response({'code':100,'msg':'用户名或密码错误'}) from .auth import Loginauth class BookView(ViewSet): authentication_classes = [Loginauth] def list(self,request): print(request.user) #User object (1) print(request.user.name) # 当前登录用户 #qx print(request.auth) # 用得少 72e37d8c-1088-4688-8f23-8459ee191615 return Response("你好:%s,你看到了好多书啊" % request.user.name)
路由:
认证类取数据
请求地址取token:token = request.query_params.get('token')
请求头取token:
请求体取token:token = request.data.get('token')
权限组件
系统中有普通用户,超级用户,超级管理员,分权限访问,有权限可以进这个接口,没权限就不能访问
使用步骤:
1、写一个类,继承BasePermission
2、重写has_permission
3、在方法中校验用户是否权限,如果有就返回True,如果没有,就返回False
因为执行在认证之后,所以从request.user中取出当前用户,判断权限
4、在视图类中局部使用,在settings中全局使用,局部可以禁用
class PublishView(ViewSet):
permission_classes = [UserPermission] (局部使用)
全局使用:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'app01.auth.LoginAuth' ], 'DEFAULT_PERMISSION_CLASSES': [ 'app01.permissions.UserPermission', ], }
from rest_framework.permissions import BasePermission class Userpermission(BasePermission): # 重写源码中的has_permission def has_permission(self, request, view): # 要在登录认证后执行,才能取到request.user.user_type
if request.user.user_type == 3: return True else: self.message = '您的用户等级为%s,无权限访问' % (request.user.get_user_type_display()) return False
认证在权限后面才能取到上述值
视图类
django项目国际化
# 配置文件中--->以后所有英文都会转成中文 INSTALLED_APPS = [ 'rest_framework' ] LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False
频率组件
控制一个接口,访问频次,例如一分钟访问几次
对接口进行访问次数限制
使用步骤:
1、写一个类,继承一个SimpleRateThrottle
2、重写get_cache_key,返回什么就以什么做限制,IP限制,用户id限制
3、写一个类属性 例如scope = 'drf_day08'
4、配置文件中配置
'DEFAULT_THROTTLE_RATES': {
'drf_day08': '3/m', # 一分钟访问三次 5/s,m,h,d
},
5、局部使用,全局使用,局部禁用
class PublishView(ViewSet):
throttle_classes = [IPRateThrottle]
6、全局使用
'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.IPRateThrottle'], (这里的名字根据throttling.py的命名来写
)
hrottling.py
id限制
ip限制
view.py
排序
只有五个接口中的查询所有,才涉及到排序
查询所有用户
使用步骤
1、必须写在继承:GenericAPIView 类的视图类中才行
2、配置类属性:
filter_backends = [OrderingFilter]
ordering_fields=['id','user_type'] #可以排序的字段
3、使用
http://127.0.0.1:8000/user/?ordering=user_type #用户类型升序排
http://127.0.0.1:8000/user/?ordering=-user_type #用户类型降序排
http://127.0.0.1:8000/user/?ordering=user_type,-id#先按用户类型升序排,如果用户类型一样,再按id降序排
频率源码