import type { Permission } from "@/lib/constants/auth"; import { forbidden } from "@/modules/auth/errors"; import type { AuthContext } from "@/modules/auth/rbac"; export type ServiceAuthContext = Extract; /** 从 middleware 注入的请求头解析宿主鉴权上下文 */ export function parseServiceAuth(request: Request): ServiceAuthContext { const authType = request.headers.get("x-auth-type"); if (authType !== "service") { throw forbidden("需要宿主 Service Token"); } const customerId = request.headers.get("x-customer-id"); if (!customerId) { throw forbidden("缺少客户标识"); } const permissionsRaw = request.headers.get("x-permissions") ?? ""; const permissions = permissionsRaw .split(",") .map((p) => p.trim()) .filter(Boolean) as Permission[]; return { type: "service", customerId, permissions, }; } /** 校验请求体 customer_id 与 token 租户一致 */ export function assertCustomerMatch( auth: ServiceAuthContext, bodyCustomerId: string, ): void { if (auth.customerId !== bodyCustomerId) { throw forbidden("customer_id 与令牌租户不匹配"); } }