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,结束!

原文地址:https://www.cnblogs.com/noteaddr/p/12937030.html