Django: 使用django-rest-framework-jwt時自定義user表(且未繼承auth.user表)


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
= []

 


免責聲明!

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



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