1
0
forked from erp-dev/erp
Files
erpnew/flower/auth.py

84 lines
3.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from ninja.security import HttpBearer
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
import logging
logger = logging.getLogger(__name__)
# ==================== 自定义 JWT 认证 for Django Ninja ====================
class JWTAuth(HttpBearer):
"""
Django Ninja 的 JWT 认证类
兼容 rest_framework_simplejwt
与 DRF 使用相同的认证逻辑,验证 JWT Token 并获取用户
"""
def authenticate(self, request, token):
jwt_authenticator = JWTAuthentication()
try:
# 验证 token 并获取用户
validated_token = jwt_authenticator.get_validated_token(token)
user = jwt_authenticator.get_user(validated_token)
# 记录认证成功
logger.debug(f"JWT 认证成功: user={user.username}")
return user
except (InvalidToken, TokenError) as e:
logger.warning(f"JWT 认证失败: {str(e)}")
return None
class JWTAuthWithEmployee(HttpBearer):
"""
Django Ninja 的 JWT 认证类(要求必须有员工身份)
与 CustomTokenObtainPairView 的逻辑一致:
- 验证 JWT Token
- 验证用户必须有关联的员工信息
"""
def __call__(self, request):
"""
重写 __call__ 方法以添加调试日志
这个方法会被 Ninja 调用来执行认证
"""
logger.info(f"[JWTAuthWithEmployee.__call__] 认证被调用")
logger.info(f"[JWTAuthWithEmployee.__call__] Authorization Header: {request.META.get('HTTP_AUTHORIZATION', 'None')[:50]}...")
# 调用父类的 __call__ 方法
result = super().__call__(request)
logger.info(f"[JWTAuthWithEmployee.__call__] 认证结果: {result}")
return result
def authenticate(self, request, token):
logger.info(f"[JWTAuthWithEmployee.authenticate] 开始认证token 前 20 字符: {token[:20] if token else 'None'}...")
if not token:
logger.warning(f"[JWTAuthWithEmployee.authenticate] Token 为空")
return None
jwt_authenticator = JWTAuthentication()
try:
# 验证 token 并获取用户
validated_token = jwt_authenticator.get_validated_token(token)
user = jwt_authenticator.get_user(validated_token)
logger.info(f"[JWTAuthWithEmployee.authenticate] Token 验证成功,用户: {user.username}")
# 检查用户是否有员工身份(与登录逻辑一致)
if not hasattr(user, 'employee'):
logger.warning(f"[JWTAuthWithEmployee.authenticate] 用户 {user.username} 没有关联的员工信息")
return None # 返回 None 会导致 401 Unauthorized
logger.info(f"[JWTAuthWithEmployee.authenticate] 认证成功: user={user.username}, employee={user.employee.name}")
return user
except (InvalidToken, TokenError) as e:
logger.warning(f"[JWTAuthWithEmployee.authenticate] Token 验证失败: {str(e)}")
return None
except Exception as e:
logger.error(f"[JWTAuthWithEmployee.authenticate] 认证异常: {str(e)}", exc_info=True)
return None