132 lines
4.2 KiB
PHP
132 lines
4.2 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Http\Middleware;
|
||
|
|
|
||
|
|
use App\Models\Tenants\Tenant;
|
||
|
|
use Closure;
|
||
|
|
use Illuminate\Http\JsonResponse;
|
||
|
|
use Illuminate\Http\RedirectResponse;
|
||
|
|
use Illuminate\Http\Request;
|
||
|
|
use Symfony\Component\HttpFoundation\Response;
|
||
|
|
|
||
|
|
class SetTenantContext
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 테넌트 콘솔 새창에서 URL의 tenantId를 컨텍스트로 설정
|
||
|
|
* 메인 창의 세션에는 영향을 주지 않음
|
||
|
|
* 리다이렉트/JSON 응답의 URL을 tenant-console 경로로 자동 재작성
|
||
|
|
*/
|
||
|
|
public function handle(Request $request, Closure $next): Response
|
||
|
|
{
|
||
|
|
$tenantId = $request->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;
|
||
|
|
}
|
||
|
|
}
|