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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM