diff --git a/apps/st/.env.example b/apps/st/.env.example index 9f786831b..c0d26e6f2 100644 --- a/apps/st/.env.example +++ b/apps/st/.env.example @@ -1,7 +1,7 @@ # apps/cs/src/shared/config/env.ts 참고 NEXT_PUBLIC_PORT=3000 NEXT_PUBLIC_PROXY_HOST=http://localhost:3000 +SERVER_API_URL=http://192.168.0.102:8000 NEXT_PUBLIC_SITE_ID=CS NEXT_PUBLIC_SUB_DOMAIN=http://localhost:3000 -NEXT_PUBLIC_SERVER_API_URL=http://192.168.0.102:8000 NEXT_PUBLIC_TINY_API_KEY=t9nc4z6inquvvd5pq1vea8wcp7lb01qmqseh6egms9vpaju2 \ No newline at end of file diff --git a/apps/st/middleware.ts b/apps/st/middleware.ts index 9a2a48cb1..db6600caf 100644 --- a/apps/st/middleware.ts +++ b/apps/st/middleware.ts @@ -1,147 +1,159 @@ import { NextRequest, NextResponse } from "next/server"; + import { - CLAIM_NAME, - AUTH_USER_ID, - PORT, - PROXY_HOST, - SERVER_API_URL, - SITE_ID, - ST_SERVICE_URL, + AUTH_USER_ID, + CLAIM_NAME, + PORT, + PROXY_HOST, + SERVER_API_URL, + SITE_ID, + ST_SERVICE_URL, } from "./src/shared/config"; -const serverApiUrl = - process.env.NEXT_PUBLIC_SERVER_API_URL ?? "http://localhost:3000"; +const serverApiUrl = process.env.SERVER_API_URL ?? "http://localhost:3000"; const stServiceUrl = ST_SERVICE_URL; -const linkBackendApiHost = process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST ?? "http://localhost:8080"; +const linkBackendApiHost = + process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST ?? "http://localhost:8080"; // CSP 헤더 설정 함수 (img-src만) function addSecurityHeaders(response: NextResponse): NextResponse { - response.headers.set("Content-Security-Policy", "img-src 'self' data: https: blob:;"); - return response; + response.headers.set( + "Content-Security-Policy", + "img-src 'self' data: https: blob:;", + ); + return response; } export function middleware(req: NextRequest) { - const pathname = req.nextUrl.pathname; - const searchParams = req.nextUrl.searchParams; + const pathname = req.nextUrl.pathname; + const searchParams = req.nextUrl.searchParams; - const logMessages: string[] = [ - `[Middleware Request] ${new Date().toISOString()}`, - `[Environment]\n Mode: ${process.env.NODE_ENV}\n Port: ${PORT}\n Proxy Host: ${PROXY_HOST}\n Server API URL: ${SERVER_API_URL}\n Site ID: ${SITE_ID}\n ST Service URL: ${stServiceUrl}`, - `[Request]\n Original Pathname: ${pathname}`, - ]; + const logMessages: string[] = [ + `[Middleware Request] ${new Date().toISOString()}`, + `[Environment]\n Mode: ${process.env.NODE_ENV}\n Port: ${PORT}\n Proxy Host: ${PROXY_HOST}\n Server API URL: ${SERVER_API_URL}\n Site ID: ${SITE_ID}\n ST Service URL: ${stServiceUrl}`, + `[Request]\n Original Pathname: ${pathname}`, + ]; - // ST Service 처리 (dc의 /server/dc-service 패턴과 동일) - if (pathname.startsWith("/server/st-management-service") || pathname.startsWith("/server/st-input-service")) { - const requestHeaders = new Headers(req.headers); - const token = req.cookies.get(CLAIM_NAME)?.value; - const userId = req.cookies.get(AUTH_USER_ID)?.value; + // ST Service 처리 (dc의 /server/dc-service 패턴과 동일) + if ( + pathname.startsWith("/server/st-management-service") || + pathname.startsWith("/server/st-input-service") + ) { + const requestHeaders = new Headers(req.headers); + const token = req.cookies.get(CLAIM_NAME)?.value; + const userId = req.cookies.get(AUTH_USER_ID)?.value; - const queryParams = searchParams.toString(); - const newUrl = `${stServiceUrl}${pathname.replace("/server", "")}${ - queryParams ? `?${queryParams}` : "" - }`; + const queryParams = searchParams.toString(); + const newUrl = `${stServiceUrl}${pathname.replace("/server", "")}${ + queryParams ? `?${queryParams}` : "" + }`; - if (token) requestHeaders.set(CLAIM_NAME, token); - if (userId) requestHeaders.set(AUTH_USER_ID, userId); + if (token) requestHeaders.set(CLAIM_NAME, token); + if (userId) requestHeaders.set(AUTH_USER_ID, userId); + + logMessages.push(` Token Debug: ${token ? "EXISTS" : "MISSING"}`); + logMessages.push(` UserId Debug: ${userId ? "EXISTS" : "MISSING"}`); + logMessages.push(` ST Service Rewritten URL: ${newUrl}`); + logMessages.push("\n--------------------------------\n"); + console.log(logMessages.join("\n")); + + const response = NextResponse.rewrite(new URL(newUrl), { + headers: requestHeaders, + }); + return addSecurityHeaders(response); + } + + // 일반 Server API 처리 (ST 서비스 제외) + if ( + pathname.startsWith("/server") && + !pathname.startsWith("/server/st-management-service") && + !pathname.startsWith("/server/st-input-service") + ) { + const requestHeaders = new Headers(req.headers); + const token = req.cookies.get(CLAIM_NAME)?.value; + const userId = req.cookies.get(AUTH_USER_ID)?.value; + + const queryParams = searchParams.toString(); + const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${ + queryParams ? `?${queryParams}` : "" + }`; + + if (token) requestHeaders.set(CLAIM_NAME, token); + if (userId) requestHeaders.set(AUTH_USER_ID, userId); + + logMessages.push(` Rewritten URL: ${newUrl}`); + logMessages.push("\n--------------------------------\n"); + console.log(logMessages.join("\n")); + + const response = NextResponse.rewrite(new URL(newUrl), { + headers: requestHeaders, + }); + return addSecurityHeaders(response); + } + + if (pathname.startsWith("/attach-service")) { + const requestHeaders = new Headers(req.headers); + const token = req.cookies.get(CLAIM_NAME)?.value; + const userId = req.cookies.get(AUTH_USER_ID)?.value; + const newUrl = `${serverApiUrl}${pathname}`; + + if (token) requestHeaders.set(CLAIM_NAME, token); + if (userId) requestHeaders.set(AUTH_USER_ID, userId); + + logMessages.push(` Rewritten URL: ${newUrl}`); + logMessages.push("\n--------------------------------\n"); + console.log(logMessages.join("\n")); + + const response = NextResponse.rewrite(new URL(newUrl), { + headers: requestHeaders, + }); + return addSecurityHeaders(response); + } + + if (pathname.startsWith("/api/link")) { + const requestHeaders = new Headers(req.headers); + const token = req.cookies.get(CLAIM_NAME)?.value; + const userId = req.cookies.get(AUTH_USER_ID)?.value; + + // /api/link 경로를 제거하고 백엔드 API 경로로 변환 + const apiPath = pathname.replace("/api/link", ""); + const queryParams = searchParams.toString(); + const newUrl = `${linkBackendApiHost}${apiPath}${ + queryParams ? `?${queryParams}` : "" + }`; + + if (token) requestHeaders.set(CLAIM_NAME, token); + if (userId) requestHeaders.set(AUTH_USER_ID, userId); + + logMessages.push(` Link API Rewritten URL: ${newUrl}`); + logMessages.push("\n--------------------------------\n"); + console.log(logMessages.join("\n")); + + const response = NextResponse.rewrite(new URL(newUrl), { + headers: requestHeaders, + }); + return addSecurityHeaders(response); + } + + if (pathname === "/") { + const response = NextResponse.redirect(new URL("/statistics", req.url)); + return addSecurityHeaders(response); + } - logMessages.push(` Token Debug: ${token ? "EXISTS" : "MISSING"}`); - logMessages.push(` UserId Debug: ${userId ? "EXISTS" : "MISSING"}`); - logMessages.push(` ST Service Rewritten URL: ${newUrl}`); logMessages.push("\n--------------------------------\n"); console.log(logMessages.join("\n")); - const response = NextResponse.rewrite(new URL(newUrl), { - headers: requestHeaders, - }); + const response = NextResponse.next(); return addSecurityHeaders(response); - } - - // 일반 Server API 처리 (ST 서비스 제외) - if ( - pathname.startsWith("/server") && - !pathname.startsWith("/server/st-management-service") && - !pathname.startsWith("/server/st-input-service") - ) { - const requestHeaders = new Headers(req.headers); - const token = req.cookies.get(CLAIM_NAME)?.value; - const userId = req.cookies.get(AUTH_USER_ID)?.value; - - const queryParams = searchParams.toString(); - const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${ - queryParams ? `?${queryParams}` : "" - }`; - - if (token) requestHeaders.set(CLAIM_NAME, token); - if (userId) requestHeaders.set(AUTH_USER_ID, userId); - - logMessages.push(` Rewritten URL: ${newUrl}`); - logMessages.push("\n--------------------------------\n"); - console.log(logMessages.join("\n")); - - const response = NextResponse.rewrite(new URL(newUrl), { - headers: requestHeaders, - }); - return addSecurityHeaders(response); - } - - if (pathname.startsWith("/attach-service")) { - const requestHeaders = new Headers(req.headers); - const token = req.cookies.get(CLAIM_NAME)?.value; - const userId = req.cookies.get(AUTH_USER_ID)?.value; - const newUrl = `${serverApiUrl}${pathname}`; - - if (token) requestHeaders.set(CLAIM_NAME, token); - if (userId) requestHeaders.set(AUTH_USER_ID, userId); - - logMessages.push(` Rewritten URL: ${newUrl}`); - logMessages.push("\n--------------------------------\n"); - console.log(logMessages.join("\n")); - - const response = NextResponse.rewrite(new URL(newUrl), { - headers: requestHeaders, - }); - return addSecurityHeaders(response); - } - - if (pathname.startsWith("/api/link")) { - const requestHeaders = new Headers(req.headers); - const token = req.cookies.get(CLAIM_NAME)?.value; - const userId = req.cookies.get(AUTH_USER_ID)?.value; - - // /api/link 경로를 제거하고 백엔드 API 경로로 변환 - const apiPath = pathname.replace("/api/link", ""); - const queryParams = searchParams.toString(); - const newUrl = `${linkBackendApiHost}${apiPath}${ - queryParams ? `?${queryParams}` : "" - }`; - - if (token) requestHeaders.set(CLAIM_NAME, token); - if (userId) requestHeaders.set(AUTH_USER_ID, userId); - - logMessages.push(` Link API Rewritten URL: ${newUrl}`); - logMessages.push("\n--------------------------------\n"); - console.log(logMessages.join("\n")); - - const response = NextResponse.rewrite(new URL(newUrl), { - headers: requestHeaders, - }); - return addSecurityHeaders(response); - } - - if (pathname === "/") { - const response = NextResponse.redirect(new URL("/statistics", req.url)); - return addSecurityHeaders(response); - } - - logMessages.push("\n--------------------------------\n"); - console.log(logMessages.join("\n")); - - const response = NextResponse.next(); - return addSecurityHeaders(response); } export const config = { - matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/"], + matcher: [ + "/server/:path*", + "/attach-service/:path*", + "/api/link/:path*", + "/", + ], }; diff --git a/apps/st/src/shared/config/env.ts b/apps/st/src/shared/config/env.ts index 458dfa3a6..634bb7f15 100644 --- a/apps/st/src/shared/config/env.ts +++ b/apps/st/src/shared/config/env.ts @@ -1,7 +1,7 @@ export const PORT = process.env.NEXT_PUBLIC_PORT || "3000"; export const PROXY_HOST = process.env.NEXT_PUBLIC_PROXY_HOST || `http://localhost:${PORT}`; -export const SERVER_API_URL = process.env.NEXT_PUBLIC_SERVER_API_URL; +export const SERVER_API_URL = process.env.SERVER_API_URL; export const AUTH_LOGIN_REDIRECT_URL = process.env.NEXT_PUBLIC_AUTH_LOGIN_REDIRECT_URL || "/auth/login"; export const SITE_ID = process.env.NEXT_PUBLIC_SITE_ID || "ST";