一、认证:
1、安装和配置
安装:pip install djangorestframework-jwt
配置:
settings.py下配置
#注册到apps中
INSTALLED_APPS = [
'rest_framework_jwt',
]
#设置token的过期时间
import datetime
JWT_AUTH = {
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
'JWT_AUTH_HEADER_PREFIX': 'JWT', #前缀需要加jwt
}
2、自己写一个auth.py认证类,解析前端传递过来的token
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.serializers import jwt_decode_handler,jwt_get_username_from_payload
import jwt
from user import models
'''用户认证模块,校验用户是否登录了。有些接口是需要登录的用户才能访问。'''
class MyJWTAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.META.get('HTTP_AUTHORIZATION')
if token:
#jwt通过了通过三段tokken,取出payload的方法,并且有校验功能
try:
payload = jwt_decode_handler(token)
username = payload.get('username')
user = models.User.objects.get(id=payload.get('user_id'))
role = user.role
return (username,{'token':token,'id':payload.get('user_id'),'role':role})
#通过reuqest.user获取元组的第一个元素
#通过request.auth获取元组的第二元素
except jwt.ExpiredSignature:
msg = {'code':104,'msg':'token过期'}
raise AuthenticationFailed(msg)
except jwt.DecodeError:
msg= {'code':104,'msg':'token非法'}
raise AuthenticationFailed(msg)
except jwt.InvalidTokenError:
msg={'code':104,'msg':'非法用户'}
raise AuthenticationFailed(msg)
except Exception as e:
msg=str(e)
raise AuthenticationFailed(msg)
raise AuthenticationFailed({'code':104,'msg':'请求方式错误,请携带token'})
3、视图类中写登录逻辑
#生成token
def _get_token(user):
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
#传递用户对象,获取token
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
return token
#用户登录的view
class UserView(ViewSet):
#登录不需要认证
authentication_classes = []
#datail=True的时候,查询字符串携带pk
@action(methods=['POST',],detail=False)
def login(self,request,*args,**kwargs):
username = request.data.get('username')
password = request.data.get('password')
try:
#用户存在,则一定能拿到用户对象
user = models.User.objects.get(username=username)
ret = user.check_password(password)
except Exception as e:
return ApiResponse(msg='登录失败',code=104,data={'errors':'用户不存在'})
# ret = auth.authenticate(request,**request.data)
if ret:
token = _get_token(user)
return ApiResponse(msg='登录成功',code=100,role=user.role,data={'token':token,'username':username})
else:
return ApiResponse(msg='用户名或密码错误',code=101)
4、使用;
全局使用:在settings.py中配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
# 自己写的认证类
'studentSystemt.apps.user.authen.MyJWTAuthentication'
],
}
局部使用:
#导入自己写的视图类模块
import authen
class StudentHomeView(ViewSet):
#将自己写的认证类写入
authentication_classes = [authen.MyJWTAuthentication]
二、权限:前提要有认证类,认证成功后从会走权限类
作用:给视图设置权限,让普通用户操作不了管理员才能操作的视图类
1、自己写一个权限类:权限类可以写多个,根据情况给不同视图配置
class SuperAdminPermission(BasePermission):
#重写has_permission方法
def has_permission(self,request,view):
#view是视图类的对象,拿到视图类的东西
#不是超级用户不能访问,由于认证已经通过了,在request.user中就可以拿到用户
user= models.User.objects.get(username=request.user)
if user.role==1:
return True
#return True代表能够访问,负责不能访问
else:
return False
2、使用
全局使用:settings.py中配置,一般不会配置全局使用
REST_FRAMEWORK={
'DEFAULT_PERMISSION_CLASSES':[‘权限类所在位置’],
}
局部使用:
在视图类前面加上:
from . import permission
class AdminView():
permission_classes=[permision.SuperAdminPermission]
三、频率类
作用:设置用户的访问频率
1、自己写一个频率类
#这是一个对应ip进行限流的频率类
from rest_framework.throttling import SimpleRateThrottle
class MyThrottle(SimpleRateThrottle):
#在settings中配置频率时使用到的关键字,有scope来指定
scope = 'IP'
def get_cache_key(self,request,view):
#这里return什么,就以什么作为限制,这里限制ip,直接return ip就可以
return reuqest.META.get('REMOTE_ADDR')
2、使用频率类
全局使用:一般使用全局使用
在settings.py中
REST_FRAMEWORK={
'DEFAULT_THROTTLE_CLASSES':(
' utils.throttling.MyThrottle'
),
'DEFAULT_THROTTLE_RATES':{
'IP':'3/m' #一个ip一分钟只能访问3次
}
}
局部使用:在视图类开头设置
setings中必须配置访问频率
REST_FRAMEWORK={
'DEFAULT_THROTTLE_RATES':{
'IP':'3/m' #一个ip一分钟只能访问3次
}
}
from utils.throttling import MyThrottle
class xxx(APIView):
throttle_classes=[MyThrottle,]
def get(self,request):
passs