from pathlib import Path from zoneinfo import ZoneInfo import pydash from django.conf import settings from jwt import JWT, jwk_from_pem from jwt.exceptions import JWTDecodeError from jwt.utils import get_time_from_int from rest_framework import exceptions from rest_framework.authentication import BaseAuthentication from rest_framework.response import Response public_key_pem_公钥 = Path( settings.BASE_DIR ).joinpath( "django_jwt_token/public.pem" ).read_bytes( ) instance = JWT( ) from rest_framework.permissions import BasePermission from rest_framework.exceptions import AuthenticationFailed class Jwt权限认证( BasePermission ): """自定义JWT认证权限类""" def has_permission( self, request, view ): """ 必须实现这个方法,返回 True 表示有权限,False 表示无权限 :param request: 请求对象 :param view: 视图对象 :return: bool """ # 获取 token(从 Authorization header 或 cookie) auth_header = request.headers.get( 'Authorization', '' ) token = request.data.get( "token", None ) Authorization = pydash.get( obj=request.headers, path="Authorization" ) print( "有作用了啦" ) print( "拿到token了吗?", Authorization ) # ✅ 正确:使用公钥进行验证 verifying_key = jwk_from_pem( pem_content=public_key_pem_公钥 ) # 解码验证 JWT received_message = instance.decode( message=Authorization, key=verifying_key, do_time_check=True ) print( f"解码后的消息: {received_message}" ) def has_object_permission( self, request, view, obj ): pass class Jwt身份认证( BaseAuthentication ): def authenticate( self, request ): try: Authorization = request.headers.get( "Authorization", "" ) # ✅ 正确:使用公钥进行验证 verifying_key = jwk_from_pem( pem_content=public_key_pem_公钥 ) # 解码验证 JWT received_message = instance.decode( message=Authorization, key=verifying_key, do_time_check=True ) 过期时间戳 = pydash.get( obj=received_message, path="exp" ) time_过期日间 = get_time_from_int( 过期时间戳 ).astimezone( tz=ZoneInfo( key="Asia/Shanghai" ) ) print( "过期的时间为:", time_过期日间, received_message ) return received_message, time_过期日间, except exceptions.AuthenticationFailed: msg = "===============" raise "认证失败" except JWTDecodeError as e: print( '999999999999999999999', str( e ) ) # 如果你想保留原始异常链 raise AuthenticationFailed( f"Token无效: {str( e )}" ) # raise f"Token无效: {str( e )}" def authenticate_header( self, request ): pass """ 返回 HTTP 401 响应时,告诉客户端应该使用哪种认证方式 """ return 'Bearer'