91 lines
3.0 KiB
Python
91 lines
3.0 KiB
Python
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'
|