diff --git a/gvsds/auth.py b/gvsds/auth.py index 91f4232f..84f8de6c 100644 --- a/gvsds/auth.py +++ b/gvsds/auth.py @@ -9,18 +9,16 @@ SimpleJWT 的 JWTAuthentication 在 __init__ 中调用 django.contrib.auth.get_u 同时支持从 Authorization 请求头和 HttpOnly Cookie 读取 JWT, 以兼容前端基于 Cookie 的认证方式(credentials: 'include')。 -额外职责:JWT 认证成功后立即解析当前角色上下文(current_role / current_company_uuid / -current_tenant_uuid),填充到 request 对象。这解决了 Django 中间件在 DRF 认证之前运行、 +额外职责:JWT 认证成功后立即解析当前角色上下文(ResolveRoleContext, +唯一实现位于 gvsdsdk.auth.middleware,与 CurrentRoleMiddleware 共用)。 +这解决了 Django 中间件在 DRF 认证之前运行、 导致中间件无法获取已认证用户的问题。 """ -import logging -from django.core.exceptions import ObjectDoesNotExist from rest_framework_simplejwt.authentication import JWTAuthentication from gvsds.apps.core.models import User - -_logger = logging.getLogger(__name__) +from gvsdsdk.auth.middleware import ResolveRoleContext #: 存储 Access Token 的 Cookie 名称 JWT_ACCESS_COOKIE = 'AccessToken' @@ -28,66 +26,6 @@ JWT_ACCESS_COOKIE = 'AccessToken' JWT_REFRESH_COOKIE = 'RefreshToken' -def ResolveRoleContext(request, user): - """解析当前角色上下文,填充 request.current_role / current_company_uuid / current_tenant_uuid - - 从 CurrentRoleUUID Cookie 读取角色 UUID,查询 UserRole + Role, - 设置 request.current_role / current_company_uuid / current_tenant_uuid。 - - Args: - request: HTTP 请求对象(会被原地修改) - user: 已认证的 User 实例 - """ - # 确保默认值(防止重复调用时残留旧值) - request.current_role = None - request.current_company_uuid = None - request.current_tenant_uuid = None - - if not user or not getattr(user, 'is_authenticated', False): - if hasattr(user, 'IsAuthenticated'): - if not user.IsAuthenticated: - return - else: - return - - from gvsdsdk.models import UserRole, Role - from gvsdsdk.model_utils import UUIDObj - - role_uuid_str = request.COOKIES.get('CurrentRoleUUID', '') - if not role_uuid_str: - _logger.warning('[ResolveRoleContext] 已认证用户 %s 无 CurrentRoleUUID cookie', user) - return - - try: - role_uuid_bytes = UUIDObj(role_uuid_str).bytes - user_role = UserRole.objects.filter( - UserUUID=user.UserUUID, - RoleUUID=role_uuid_bytes - ).first() - if not user_role: - _logger.warning('[ResolveRoleContext] cookie=%s 但 UserRole 未找到 (user=%s)', - role_uuid_str[:36], user) - return - # 单独查询 Role 实例(Role.TenantUUID 提供租户信息) - role = Role.objects.filter(RoleUUID=role_uuid_bytes).first() - if role: - request.current_role = role - # 从 Role 实例获取租户 UUID(UUIDObj,FormService 会转 bytes) - request.current_tenant_uuid = role.TenantUUID - # UserRole.CompanyUUID 是 UUIDField,直接赋值 - if user_role.CompanyUUID: - request.current_company_uuid = user_role.CompanyUUID - _logger.info('[ResolveRoleContext] cookie=%s, role=%s, tenant=%s, company=%s', - role_uuid_str[:36], - getattr(role, 'RoleName', None) if role else None, - request.current_tenant_uuid, - request.current_company_uuid) - except (ValueError, KeyError, ObjectDoesNotExist) as e: - _logger.warning('[ResolveRoleContext] cookie=%s 解析失败: %s', role_uuid_str[:36], e) - except Exception: - _logger.exception('[ResolveRoleContext] 解析当前角色失败') - - class CustomJWTAuthentication(JWTAuthentication): """JWT 认证——使用项目自定义 User 模型(core.User)