drf 中自定义登录 以及token验证
1,在drf项目目录下的util文件夹中创建login.py 文件:
from rest_framework.views import APIView from users.models import UserProfile from utils.myresponse import APIResponse from django.contrib.auth import authenticate import jwt, time from new_pay.settings import SECRET_KEY as key #django项目的密钥 class MyLogin(APIView): # 自定义产生token的函数 def post(self, request, *args, **kwargs): have_user = UserProfile.objects.filter(username=request.data.get('username', None)) if not have_user: return APIResponse(1, '改用户不存在', "") login_info = { 'username': request.data.get('username'), 'password': request.data.get('password') } user = authenticate(**login_info) if not user: return APIResponse(1, '账号或密码错误', "") set = { 'exp': int(time.time() + 60 * 60 * 24), # 超时时间 'iat': int(time.time()), # 生成TOKEN时间 'username': user.username, } token = jwt.encode(set, key, algorithm='HS256') #使用pyjwt的 jwt.encode 函数加密生成Token return APIResponse(0, 'success', {'token': token, 'level': user.level, 'username': user.username}) # 返回信息
2,自定义login方法生成,下一步 编写自定义验证器:
from rest_framework.authentication import BaseAuthentication from rest_framework import exceptions from jwt import ExpiredSignatureError, InvalidAlgorithmError, InvalidSignatureError, DecodeError from spuser.models import LogInfo def login_log(user): # 登录日志函数 if user.level == 1: pos = '管理员' elif user.level == 2: pos = '代理' else: pos = "商户" content = "{}:{}登录该站点".format(pos, user.username) create_dist = { "log_type": 0, "content": content, "user_id": user.id, } LogInfo.objects.create(**create_dist) class TokenAuthentication(BaseAuthentication): def authenticate(self, request): token = request.META.get('HTTP_TOKEN', None) if not token: raise exceptions.AuthenticationFailed('请提交token') # exceptions 会被自定义的错误处理捕捉,并返回 try: decode_info = jwt.decode(token, key, algorithms='HS256') # 使用pyjwt.decode 解密token ,获取相关用户 print(decode_info) user = UserProfile.objects.get(username=decode_info['username']) login_log(user) # 用户登录的日志 return (user, None) #返回的数据由 request.user 接收 except ExpiredSignatureError: raise exceptions.AuthenticationFailed('Token已过期,请重新登录') except: raise exceptions.AuthenticationFailed('验证失败')
3,结束!