diff options
Diffstat (limited to 'app/api')
| -rw-r--r-- | app/api/auth/[...nextauth]/route.ts | 27 | ||||
| -rw-r--r-- | app/api/test/headers/route.ts | 80 |
2 files changed, 105 insertions, 2 deletions
diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts index d6ec807f..58566cd6 100644 --- a/app/api/auth/[...nextauth]/route.ts +++ b/app/api/auth/[...nextauth]/route.ts @@ -449,12 +449,35 @@ export const authOptions: NextAuthOptions = { }, async redirect({ url, baseUrl }) { + // 상대 경로인 경우 baseUrl과 결합 if (url.startsWith("/")) { return `${baseUrl}${url}`; } - else if (new URL(url).origin === baseUrl) { - return url; + + // 절대 URL인 경우: 허용된 도메인 목록 확인 + try { + const urlObj = new URL(url); + const allowedDomains = [ + "shidataroom.com", + "partners.sevcp.com", + "sevcp.com", + "localhost" // 개발 환경 + ]; + + // 허용된 도메인이면 그대로 반환 + if (allowedDomains.includes(urlObj.hostname)) { + return url; + } + + // 기존 로직: baseUrl과 origin이 같으면 허용 + if (urlObj.origin === baseUrl) { + return url; + } + } catch { + console.error('Invalid redirect URL:', url); } + + // 허용되지 않은 URL은 baseUrl로 리다이렉트 return baseUrl; }, }, diff --git a/app/api/test/headers/route.ts b/app/api/test/headers/route.ts new file mode 100644 index 00000000..70c14564 --- /dev/null +++ b/app/api/test/headers/route.ts @@ -0,0 +1,80 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { headers } from 'next/headers'; + +/** + * 리버스 프록시 헤더 전달 테스트 API + * + * 접속 방법: + * - https://shidataroom.com/api/test/headers + * - https://partners.sevcp.com/api/test/headers + * - https://sevcp.com/api/test/headers + * + * 각 도메인에서 헤더가 올바르게 전달되는지 확인 + */ +export async function GET(request: NextRequest) { + const headersList = await headers(); + + // 중요한 헤더들 수집 + const host = headersList.get('host'); + const xForwardedProto = headersList.get('x-forwarded-proto'); + const xForwardedHost = headersList.get('x-forwarded-host'); + const xForwardedFor = headersList.get('x-forwarded-for'); + const xRealIp = headersList.get('x-real-ip'); + + // 현재 계산된 origin + const proto = xForwardedProto || 'http'; + const computedOrigin = `${proto}://${host}`; + + // request.nextUrl의 origin (Next.js가 인식하는 origin) + const nextUrlOrigin = request.nextUrl.origin; + + return NextResponse.json({ + success: true, + message: '리버스 프록시 헤더 정보', + headers: { + host, + 'x-forwarded-proto': xForwardedProto, + 'x-forwarded-host': xForwardedHost, + 'x-forwarded-for': xForwardedFor, + 'x-real-ip': xRealIp, + }, + computed: { + origin: computedOrigin, + nextUrlOrigin, + isCorrect: computedOrigin === nextUrlOrigin, + }, + recommendations: { + dmz_nginx: { + required: [ + 'proxy_set_header Host $host;', + 'proxy_set_header X-Forwarded-Proto $scheme;', + 'proxy_set_header X-Forwarded-Host $host;', + 'proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;', + 'proxy_set_header X-Real-IP $remote_addr;', + ] + }, + ap_nginx: { + required: [ + 'proxy_set_header Host $host;', + 'proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;', + 'proxy_set_header X-Forwarded-Host $http_x_forwarded_host;', + 'proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;', + 'proxy_set_header X-Real-IP $http_x_real_ip;', + ] + } + }, + test: { + description: '각 도메인에서 이 API를 호출하여 헤더가 올바른지 확인하세요', + expected: { + 'shidataroom.com': 'computed.origin should be "https://shidataroom.com"', + 'partners.sevcp.com': 'computed.origin should be "https://partners.sevcp.com"', + 'sevcp.com': 'computed.origin should be "https://sevcp.com"', + } + } + }, { + headers: { + 'Content-Type': 'application/json', + } + }); +} + |
