1
0
forked from erp-dev/erp

feat: sse && multi_merchant completed

This commit is contained in:
2025-11-11 10:56:20 +08:00
parent b2078dfa46
commit 2aafb93aad
43 changed files with 2445 additions and 244 deletions

83
flower/auth.py Normal file
View File

@@ -0,0 +1,83 @@
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