route('tenantId'); if (! $tenantId) { abort(404, '테넌트 ID가 필요합니다.'); } $tenant = Tenant::find($tenantId); if (! $tenant) { abort(404, '테넌트를 찾을 수 없습니다.'); } // 요청 범위에서만 테넌트 컨텍스트 설정 (세션 변경 없음) $request->attributes->set('tenant_console_id', $tenantId); $request->attributes->set('tenant_console', $tenant); $request->attributes->set('tenant_id', (int) $tenantId); // 뷰에서 사용할 수 있도록 공유 view()->share('consoleTenant', $tenant); view()->share('consoleTenantId', $tenantId); view()->share('isTenantConsole', true); // layouts.app → layouts.tenant-console 자동 전환 // tenant-override 디렉토리를 뷰 경로 최우선으로 추가 app('view')->getFinder()->prependLocation(resource_path('views/tenant-override')); $response = $next($request); // 리다이렉트 응답: URL을 tenant-console 경로로 재작성 if ($response instanceof RedirectResponse) { $response = $this->rewriteRedirect($response, $tenantId); } // JSON 응답: redirect 키의 URL 재작성 if ($response instanceof JsonResponse) { $response = $this->rewriteJsonRedirect($response, $tenantId); } // HX-Redirect 헤더 재작성 if ($response->headers->has('HX-Redirect')) { $hxUrl = $response->headers->get('HX-Redirect'); $response->headers->set('HX-Redirect', $this->prefixUrl($hxUrl, $tenantId)); } return $response; } /** * 리다이렉트 URL에 tenant-console 프리픽스 추가 */ private function rewriteRedirect(RedirectResponse $response, int $tenantId): RedirectResponse { $targetUrl = $response->getTargetUrl(); $response->setTargetUrl($this->prefixUrl($targetUrl, $tenantId)); return $response; } /** * JSON 응답의 redirect 키 URL 재작성 */ private function rewriteJsonRedirect(JsonResponse $response, int $tenantId): JsonResponse { $data = $response->getData(true); if (isset($data['redirect']) && is_string($data['redirect'])) { $data['redirect'] = $this->prefixUrl($data['redirect'], $tenantId); $response->setData($data); } return $response; } /** * URL에 /tenant-console/{tenantId} 프리픽스 추가 * 이미 tenant-console 경로면 그대로 반환 */ private function prefixUrl(string $url, int $tenantId): string { $consolePrefix = "/tenant-console/{$tenantId}"; // 이미 tenant-console 경로면 그대로 if (str_contains($url, '/tenant-console/')) { return $url; } // 절대 URL (https://...) 에서 path 추출 $parsed = parse_url($url); $path = $parsed['path'] ?? '/'; // /api/ 경로는 재작성하지 않음 if (str_starts_with($path, '/api/')) { return $url; } // 프리픽스 추가 $newPath = $consolePrefix . $path; $query = isset($parsed['query']) ? '?' . $parsed['query'] : ''; $fragment = isset($parsed['fragment']) ? '#' . $parsed['fragment'] : ''; // 호스트가 있으면 포함 if (isset($parsed['scheme'])) { $host = $parsed['scheme'] . '://' . $parsed['host']; $port = isset($parsed['port']) ? ':' . $parsed['port'] : ''; return $host . $port . $newPath . $query . $fragment; } return $newPath . $query . $fragment; } }