From 7f8e5fe9f9466b077b273726fb160d6a40e25091 Mon Sep 17 00:00:00 2001 From: bicochan Date: Tue, 7 Jul 2026 18:02:18 +0900 Subject: [PATCH] =?UTF-8?q?[as]=20feat:=20auth=20service=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(BaseLayout=20DI=20=ED=8C=A8=ED=84=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/as/app/api/auth/logout/route.ts | 18 ++++++++++++++++++ apps/as/src/app/layouts/base-layout.tsx | 6 ++++-- apps/as/src/entities/auth/api/auth-service.ts | 17 +++++++++++++++-- .../src/entities/auth/model/auth-interface.ts | 11 +---------- 4 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 apps/as/app/api/auth/logout/route.ts diff --git a/apps/as/app/api/auth/logout/route.ts b/apps/as/app/api/auth/logout/route.ts new file mode 100644 index 000000000..d040a8f49 --- /dev/null +++ b/apps/as/app/api/auth/logout/route.ts @@ -0,0 +1,18 @@ +import { cookies } from "next/headers"; +import { NextResponse } from "next/server"; + +import { + ACCESS_TOKEN, + AUTH_USER_ID, + CLAIM_NAME, + REFRESH_TOKEN, +} from "@/shared/config"; + +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); + return NextResponse.json({ message: "Logged out" }, { status: 200 }); +} diff --git a/apps/as/src/app/layouts/base-layout.tsx b/apps/as/src/app/layouts/base-layout.tsx index fc84a5e3e..e0c1c9bb0 100644 --- a/apps/as/src/app/layouts/base-layout.tsx +++ b/apps/as/src/app/layouts/base-layout.tsx @@ -5,10 +5,11 @@ import { usePathname, useRouter } from "next/navigation"; import { useQueryClient } from "@tanstack/react-query"; -import { useMenuStore } from "@/shared/lib"; -import { PageLayout } from "@/shared/ui/page-layout"; +import { authService } from "@/entities/auth"; import type { MenuItem } from "@/entities/menu"; import { BaseLayout } from "@common/components"; +import { useMenuStore } from "@/shared/lib"; +import { PageLayout } from "@/shared/ui/page-layout"; interface BaseLayoutWrapperProps { children: React.ReactNode; @@ -32,6 +33,7 @@ export function BaseLayoutWrapper({ children }: BaseLayoutWrapperProps) { return ( diff --git a/apps/as/src/entities/auth/api/auth-service.ts b/apps/as/src/entities/auth/api/auth-service.ts index 0c1730054..914b7e13e 100644 --- a/apps/as/src/entities/auth/api/auth-service.ts +++ b/apps/as/src/entities/auth/api/auth-service.ts @@ -1,7 +1,7 @@ -import { ACCESS_TOKEN, AUTH_USER_ID, CLAIM_NAME, ENDPOINT } from "@/shared/config"; +import { ACCESS_TOKEN, AUTH_LOGIN_REDIRECT_URL, AUTH_USER_ID, CLAIM_NAME, ENDPOINT } from "@/shared/config"; import { getRemainingMs } from "@common/auth"; -import { clearAuthToken, setToken, setupRefreshTimer } from "../lib/token-manager"; +import { clearAuthToken, removeToken, setToken, setupRefreshTimer } from "../lib/token-manager"; import type { AuthPayload, AuthService } from "../model/auth-interface"; async function login(payload: AuthPayload): Promise { @@ -66,9 +66,22 @@ async function silentRefresh(): Promise { } async function logout(): Promise { + try { + await fetch("/api/auth/logout", { + method: "POST", + credentials: "include", + }); + } catch (error) { + console.error("Logout API failed:", error); + } + clearAuthToken(); + removeToken("site-id-key"); + removeToken("site-theme-key"); + if (typeof window !== "undefined") { window.dispatchEvent(new CustomEvent("auth:logout")); + window.location.href = AUTH_LOGIN_REDIRECT_URL; } } diff --git a/apps/as/src/entities/auth/model/auth-interface.ts b/apps/as/src/entities/auth/model/auth-interface.ts index fb6e10630..86b6453e5 100644 --- a/apps/as/src/entities/auth/model/auth-interface.ts +++ b/apps/as/src/entities/auth/model/auth-interface.ts @@ -1,10 +1 @@ -export interface AuthPayload { - userId: string; - password: string; -} - -export interface AuthService { - login(payload: AuthPayload): Promise; - silentRefresh(): Promise; - logout(): Promise; -} +export type { AuthPayload, AuthService } from "@common/auth";