drf-jwt自定義認證
阿新 • • 發佈:2022-03-23
import jwt from rest_framework_jwt.authentication import BaseAuthentication,BaseJSONWebTokenAuthentication from rest_framework.exceptions import AuthenticationFailed from rest_framework_jwt.authentication import jwt_decode_handler from rest_framework_jwt.authentication import get_authorization_header,jwt_get_username_from_payload from rest_framework import exceptions from app01 import models class MyToken(BaseJSONWebTokenAuthentication): def authenticate(self, request): jwt_value=str(request.META.get('HTTP_AUTHORIZATION')) # 認證 try: payload = jwt_decode_handler(jwt_value) except Exception: raise exceptions.AuthenticationFailed("認證失敗") user=self.authenticate_credentials(payload) return user,None class MyBaseAuthentication(BaseAuthentication): def authenticate(self, request): jwt_value=request.META.get('HTTP_AUTHORIZATION') if jwt_value: try: #jwt提供了通過三段token,取出payload的方法,並且有校驗功能 payload=jwt_decode_handler(jwt_value) except jwt.ExpiredSignature: raise AuthenticationFailed('簽名過期') except jwt.InvalidTokenError: raise AuthenticationFailed('使用者非法') except Exception as e: # 所有異常都會走到這 raise AuthenticationFailed(str(e)) # 因為payload就是使用者資訊的字典 print(payload) # return payload, jwt_value # 需要得到user物件, # 第一種,去資料庫查 # user=models.User.objects.get(pk=payload.get('user_id')) # 第二種不查庫 user=models.User(id=payload.get('user_id'),username=payload.get('username')) return user,jwt_value # 沒有值,直接拋異常 raise AuthenticationFailed('您沒有攜帶認證資訊') class MyBaseJSONWebTokenAuthentication(BaseJSONWebTokenAuthentication): def authenticate(self, request): jwt_value=request.META.get('HTTP_AUTHORIZATION') if jwt_value: try: #jwt提供了通過三段token,取出payload的方法,並且有校驗功能 payload=jwt_decode_handler(jwt_value) except jwt.ExpiredSignature: raise AuthenticationFailed('簽名過期') except jwt.InvalidTokenError: raise AuthenticationFailed('使用者非法') except Exception as e: # 所有異常都會走到這 raise AuthenticationFailed(str(e)) #BaseJSONWebTokenAuthentication 這個類裡面有獲取使用者物件的方法 user=self.authenticate_credentials(payload) return user,jwt_value # 沒有值,直接拋異常 #這裡得分情況,如果是遊客訪問的話,還是需要讓遊客能訪問到 #這裡就寫的 沒有token的不讓訪問 raise AuthenticationFailed('您沒有攜帶認證資訊')