From 8e156485c3593cdeb8081bc5cafdde31dae0f392 Mon Sep 17 00:00:00 2001 From: swcho Date: Thu, 6 Nov 2025 09:32:01 +0900 Subject: [PATCH] =?UTF-8?q?feat,=20fix:=20-=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80(=EC=88=98?= =?UTF-8?q?=EC=A0=95=EC=A4=91)=20-=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/api/auth/logout/route.ts | 17 ++++++++++++---- apps/fo/app/auth/login/route.ts | 12 +++++++++++ apps/fo/app/page.tsx | 3 ++- apps/sn/app/api/auth/logout/route.ts | 30 ++++++++++++++++++++++------ apps/sn/app/auth/login/route.ts | 12 +++++++++++ apps/sn/app/page.tsx | 3 ++- apps/wr/app/api/auth/logout/route.ts | 17 ++++++++++++---- apps/wr/app/auth/login/route.ts | 12 +++++++++++ apps/wr/app/page.tsx | 3 ++- 9 files changed, 92 insertions(+), 17 deletions(-) create mode 100644 apps/fo/app/auth/login/route.ts create mode 100644 apps/sn/app/auth/login/route.ts create mode 100644 apps/wr/app/auth/login/route.ts diff --git a/apps/fo/app/api/auth/logout/route.ts b/apps/fo/app/api/auth/logout/route.ts index 8832d35a3..f96bb544d 100644 --- a/apps/fo/app/api/auth/logout/route.ts +++ b/apps/fo/app/api/auth/logout/route.ts @@ -9,9 +9,18 @@ import { export async function POST() { const cookieStore = await cookies(); - cookieStore.delete(ACCESS_TOKEN); - cookieStore.delete(REFRESH_TOKEN); - cookieStore.delete(AUTH_USER_ID); - cookieStore.delete(CLAIM_NAME); + + const cookieOptions = { + httpOnly: true, + sameSite: "lax" as const, + path: "/", + maxAge: 0, // 즉시 만료 + }; + + cookieStore.set(ACCESS_TOKEN, "", cookieOptions); + cookieStore.set(REFRESH_TOKEN, "", cookieOptions); + cookieStore.set(AUTH_USER_ID, "", cookieOptions); + cookieStore.set(CLAIM_NAME, "", cookieOptions); + return NextResponse.json({ message: "Logged out" }, { status: 200 }); } diff --git a/apps/fo/app/auth/login/route.ts b/apps/fo/app/auth/login/route.ts new file mode 100644 index 000000000..d954cbaa1 --- /dev/null +++ b/apps/fo/app/auth/login/route.ts @@ -0,0 +1,12 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(request: NextRequest) { + const hostname = request.nextUrl.hostname; + const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://queen.hasuon.or.kr"; + + if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { + return NextResponse.redirect(new URL("/", request.url)); // 로컬 및 개발 환경 + } else { + return NextResponse.redirect(new URL(redirectUrl)); // 공단 환경 + } +} \ No newline at end of file diff --git a/apps/fo/app/page.tsx b/apps/fo/app/page.tsx index e9e747a1b..143dfdc90 100644 --- a/apps/fo/app/page.tsx +++ b/apps/fo/app/page.tsx @@ -9,9 +9,10 @@ import { useRouter } from "next/navigation"; export default function Home() { const router = useRouter(); const checkToken = getCookie(AUTH_USER_ID); - const hostname = window.location.hostname; useEffect(() => { + const hostname = window.location.hostname; + if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { if (!checkToken) { async function doLogin() { diff --git a/apps/sn/app/api/auth/logout/route.ts b/apps/sn/app/api/auth/logout/route.ts index fdcc9df7c..37e758731 100644 --- a/apps/sn/app/api/auth/logout/route.ts +++ b/apps/sn/app/api/auth/logout/route.ts @@ -1,5 +1,5 @@ import { cookies } from "next/headers"; -import { NextResponse } from "next/server"; +import { NextRequest, NextResponse } from "next/server"; import { ACCESS_TOKEN, AUTH_USER_ID, @@ -7,11 +7,29 @@ import { REFRESH_TOKEN, } from "@/shared/config"; -export async function POST() { +export async function POST(request: NextRequest) { const cookieStore = await cookies(); - cookieStore.delete(ACCESS_TOKEN); - cookieStore.delete(REFRESH_TOKEN); - cookieStore.delete(AUTH_USER_ID); - cookieStore.delete(CLAIM_NAME); + + // 쿠버네티스 환경: x-forwarded-host 또는 host 헤더에서 실제 도메인 가져오기 + const forwardedHost = request.headers.get("x-forwarded-host"); + const host = request.headers.get("host"); + const actualHost = forwardedHost || host || request.nextUrl.hostname; + + // 운영 환경에서 domain 설정 + const domain = actualHost.includes("hasuon.or.kr") ? ".hasuon.or.kr" : undefined; + + const cookieOptions = { + httpOnly: true, + sameSite: "lax" as const, + path: "/", + maxAge: 0, // 즉시 만료 + ...(domain && { domain }), + }; + + cookieStore.set(ACCESS_TOKEN, "", cookieOptions); + cookieStore.set(REFRESH_TOKEN, "", cookieOptions); + cookieStore.set(AUTH_USER_ID, "", cookieOptions); + cookieStore.set(CLAIM_NAME, "", cookieOptions); + return NextResponse.json({ message: "Logged out" }, { status: 200 }); } diff --git a/apps/sn/app/auth/login/route.ts b/apps/sn/app/auth/login/route.ts new file mode 100644 index 000000000..d954cbaa1 --- /dev/null +++ b/apps/sn/app/auth/login/route.ts @@ -0,0 +1,12 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(request: NextRequest) { + const hostname = request.nextUrl.hostname; + const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://queen.hasuon.or.kr"; + + if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { + return NextResponse.redirect(new URL("/", request.url)); // 로컬 및 개발 환경 + } else { + return NextResponse.redirect(new URL(redirectUrl)); // 공단 환경 + } +} \ No newline at end of file diff --git a/apps/sn/app/page.tsx b/apps/sn/app/page.tsx index cc2691f35..1babfe451 100644 --- a/apps/sn/app/page.tsx +++ b/apps/sn/app/page.tsx @@ -24,9 +24,10 @@ import { useRouter } from "next/navigation"; export default function Home() { const router = useRouter(); const checkToken = getCookie(AUTH_USER_ID); - const hostname = window.location.hostname; useEffect(() => { + const hostname = window.location.hostname; + if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { if (!checkToken) { async function doLogin() { diff --git a/apps/wr/app/api/auth/logout/route.ts b/apps/wr/app/api/auth/logout/route.ts index 8832d35a3..f96bb544d 100644 --- a/apps/wr/app/api/auth/logout/route.ts +++ b/apps/wr/app/api/auth/logout/route.ts @@ -9,9 +9,18 @@ import { export async function POST() { const cookieStore = await cookies(); - cookieStore.delete(ACCESS_TOKEN); - cookieStore.delete(REFRESH_TOKEN); - cookieStore.delete(AUTH_USER_ID); - cookieStore.delete(CLAIM_NAME); + + const cookieOptions = { + httpOnly: true, + sameSite: "lax" as const, + path: "/", + maxAge: 0, // 즉시 만료 + }; + + cookieStore.set(ACCESS_TOKEN, "", cookieOptions); + cookieStore.set(REFRESH_TOKEN, "", cookieOptions); + cookieStore.set(AUTH_USER_ID, "", cookieOptions); + cookieStore.set(CLAIM_NAME, "", cookieOptions); + return NextResponse.json({ message: "Logged out" }, { status: 200 }); } diff --git a/apps/wr/app/auth/login/route.ts b/apps/wr/app/auth/login/route.ts new file mode 100644 index 000000000..d954cbaa1 --- /dev/null +++ b/apps/wr/app/auth/login/route.ts @@ -0,0 +1,12 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(request: NextRequest) { + const hostname = request.nextUrl.hostname; + const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://queen.hasuon.or.kr"; + + if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { + return NextResponse.redirect(new URL("/", request.url)); // 로컬 및 개발 환경 + } else { + return NextResponse.redirect(new URL(redirectUrl)); // 공단 환경 + } +} \ No newline at end of file diff --git a/apps/wr/app/page.tsx b/apps/wr/app/page.tsx index feb794355..fb131e794 100644 --- a/apps/wr/app/page.tsx +++ b/apps/wr/app/page.tsx @@ -10,9 +10,10 @@ import { useRouter } from "next/navigation"; export default function Home() { const router = useRouter(); const checkToken = getCookie(AUTH_USER_ID); - const hostname = window.location.hostname; useEffect(() => { + const hostname = window.location.hostname; + if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { if (!checkToken) { async function doLogin() {