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