django_rest_frameworker jwt 是基於django自帶的認證系統(庫中的auth_user表)來實現的,
也就是說我們的用戶表(user)需要直接繼承django自帶的AbstractUser表,在此基礎上添加字段。
網上大部分的文章也是默認這么做的。
由於事先已經自定義的user表,而且沒有繼承 AbstractUser,所以需要重寫一些方法來使用我們自建的user表數據。
from rest_framework_jwt.utils import jwt_decode_handler import jwt from rest_framework.exceptions import AuthenticationFailed from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication from account.models import User class JwtAuthentication(BaseJSONWebTokenAuthentication): """ 當User表為自定義的表,而且沒有繼承自django自帶的auth.User表時,需要重寫驗證方法:authenticate """ def authenticate(self, request): token = request.META.get('HTTP_Authorization'.upper()) print(token) try: payload = jwt_decode_handler(token) except jwt.ExpiredSignature: raise AuthenticationFailed('親,token放太久了,都過期了,快去重新獲取吧!') except jwt.DecodeError: raise AuthenticationFailed('token為空或者解碼錯誤') except jwt.InvalidTokenError: raise AuthenticationFailed('不合法的token') # 得到的user對象,應該是自己user表的user對象 # print(payload) # payload內容:{'user_id': 1, 'username': '66559575', 'exp': 1620538525, 'email': '66559575@cho.cn'} user = User.objects.get(id=payload['user_id']) # user = payload return user, token
其中的關鍵就是獲取user實例,user= User.objects.get(id=payload['user_id'])
在settings.py中做如下配置,如果配置了則表示全局認證,所有接口都需要token
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ # 全局配置使用自定義的token認證 'common.JWTAuthentication.JwtAuthentication', # 使用JWT Token認證 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', # Basic類型的認證(賬號和密碼) 'rest_framework.authentication.SessionAuthentication', # Session會話認證 'rest_framework.authentication.BasicAuthentication', ], } JWT_AUTH = { # token過期時間 'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=1), # seconds=300 5分鍾 # token前綴 # 'JWT_AUTH_HEADER_PREFIX': 'JWT', }
如果沒有配置全局應用,只需要控制某視圖的權限,
則在視圖類中添加 authentication_classes = [JwtAuthentication],指定上面自定義的認證類
class ListSubSys(generics.ListAPIView): """ 獲取子系統列表 """ queryset = SubSys.objects.all() serializer_class = SubSysSerializers # 使用自定義分頁 pagination_class = CustomPagination # 模糊匹配查詢 filterset_class = sub_sys_filter.SubSysFilter # JWT認證,使用自定義的JwtAuthentication,繼承自JSONWebTokenAuthentication authentication_classes = [JwtAuthentication] # permission_classes = [IsAuthenticated]
認證功能局部使用和全局使用
# 1 全局使用(所有接口,都需要登錄才能訪問) -在配置文件中 REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["common.JWTAuthentication.JWTAuthentication", ] } #2 局部使用 -在想局部使用的視圖類上寫上下面這條 authentication_classes = [JwtAuthentication]
#3 局部禁用 -在想禁用的視圖類上
authentication_classes = []