1. 程式人生 > 其它 >28 自定義認證類

28 自定義認證類

使用jwt自帶的JSONWebTokenAuthentication認證類

需要帶jwt+空格+token,不然不認證,非常麻煩

原來的認證類返回了request.user,是auth的user,不是自己自定義的user,所以需要自定義認證類

jwt之定製認證類:token放在header裡

基於BaseAuthentication:沒有提供獲取user的方法

基於BaseJSONWebTokenAuthentication:可以由authenticate_credentials()獲取user

auth.py

# 自定義認證類
from rest_framework.authentication import
BaseAuthentication from rest_framework.exceptions import AuthenticationFailed from rest_framework_jwt.settings import api_settings jwt_decode_handler = api_settings.JWT_DECODE_HANDLER import jwt from .models import User class JwtAuthentication(BaseAuthentication): def authenticate(self, request):
# 第一步:取出前端傳入的token串(從請求頭的token中取出) jwt_value = request.META.get('HTTP_TOKEN') if jwt_value: # 驗證token是否合法 try: # 通過token,得到payload,在得到的過程中會校驗,是否過期,是否被穿該 payload = jwt_decode_handler(jwt_value) except jwt.ExpiredSignature:
raise AuthenticationFailed('簽名過期') except jwt.DecodeError: raise AuthenticationFailed('簽名驗證失敗') except jwt.InvalidTokenError: raise AuthenticationFailed('未知錯誤') print(payload) # 有沒有問題?每次都要去資料庫查使用者,效率低 # 優先用這種 user=User.objects.get(id=payload['user_id']) # 不需要查資料庫,效率高,存在缺陷, # user=User(id=payload['user_id'],username=payload['username']) return (user, jwt_value) else: # 沒帶token串,沒登入 raise AuthenticationFailed('您沒有攜帶token')

#區域性使用views.py

# 區域性使用,在檢視類中配置
from .auth import JwtAuthentication
class TestView(APIView):
    # 自己寫的認證類
    authentication_classes = [JwtAuthentication, ]

    def get(self, request):
        print(request.user) # 這就是當前登入使用者
        return Response('你必須登入,才能看到我')

#全域性使用settings.py

# 全域性使用,在配置檔案中配置
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES':['app01.auth.JwtAuthentication'], # 全域性生效

}
# 全域性使用後,區域性禁用
class LoginView(APIView):
    authentication_classes = []
    
    
# 注意:配置的所有認證,許可權,頻率。。。優先用檢視類自己的,再用配置檔案的,最後用drf內建的

補充:(settings.py)

# 補充:token過期時間很快,改改過期時間,配置7天過期
JWT_AUTH = {
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.common.jwt_response_payload_handler',
    # 過期時間7天
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
}

post測試