From 97c9cff4c7ac2b126d44bce114c489e9aa17689d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Wed, 18 Mar 2026 13:07:54 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20[internal]=20MNG=20=EB=82=B4=EB=B6=80=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EA=B5=90=ED=99=98=20=ED=85=8C=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EA=B2=80=EC=A6=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - InternalTokenService: 테넌트 소속 검사 제거 (HMAC으로 이미 신뢰) - ApiKeyMiddleware: mng_session 토큰 시 X-TENANT-ID 헤더 우선 적용 - MNG 관리자가 모든 테넌트의 BOM 산출 가능하도록 개선 --- app/Http/Middleware/ApiKeyMiddleware.php | 10 ++++++++++ app/Services/InternalTokenService.php | 13 +++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/app/Http/Middleware/ApiKeyMiddleware.php b/app/Http/Middleware/ApiKeyMiddleware.php index 70a5b4b6..2c3db683 100644 --- a/app/Http/Middleware/ApiKeyMiddleware.php +++ b/app/Http/Middleware/ApiKeyMiddleware.php @@ -89,6 +89,7 @@ public function handle(Request $request, Closure $next) // Bearer 인증 (Sanctum) $user = []; + $accessToken = null; if ($token = $request->bearerToken()) { $accessToken = PersonalAccessToken::findToken($token); if ($accessToken && $accessToken->tokenable instanceof User) { @@ -114,6 +115,15 @@ public function handle(Request $request, Closure $next) } } + // MNG 내부 통신: X-TENANT-ID 헤더로 테넌트 컨텍스트 재설정 + // mng_session 토큰(InternalTokenService 발급)인 경우에만 허용 + $headerTenantId = $request->header('X-TENANT-ID'); + if ($headerTenantId && $accessToken && $accessToken->name === 'mng_session') { + $overrideTenantId = (int) $headerTenantId; + $request->attributes->set('tenant_id', $overrideTenantId); + app()->instance('tenant_id', $overrideTenantId); + } + // 화이트리스트(인증 예외 라우트) - Bearer 토큰 없이 접근 가능 $allowWithoutAuth = [ 'api/v1/login', diff --git a/app/Services/InternalTokenService.php b/app/Services/InternalTokenService.php index 8b250508..ad1dd459 100644 --- a/app/Services/InternalTokenService.php +++ b/app/Services/InternalTokenService.php @@ -97,16 +97,9 @@ public function issueToken(int $userId, int $tenantId): ?array return null; } - // 해당 테넌트에 소속되어 있는지 확인 - $userTenant = $user->userTenants()->where('tenant_id', $tenantId)->first(); - if (! $userTenant) { - Log::warning('[InternalTokenService] User not in tenant', [ - 'user_id' => $userId, - 'tenant_id' => $tenantId, - ]); - - return null; - } + // MNG 내부 토큰 교환: 테넌트 소속 검사 생략 + // HMAC 서명으로 MNG 서버 신뢰성이 검증되었으므로, + // MNG 관리자는 모든 테넌트에 접근 가능 // 기존 mng_session 토큰 삭제 (중복 방지) $user->tokens()->where('name', 'mng_session')->delete();