diff --git a/components/layout/AppHeader.vue b/components/layout/AppHeader.vue index a76de9c..a84fe33 100644 --- a/components/layout/AppHeader.vue +++ b/components/layout/AppHeader.vue @@ -33,7 +33,7 @@
- {{ userStore.userName }} + {{ userStore.user?.name }}
{ border: none; padding: 0.5rem 1.5rem; border-radius: 6px; - transition: background 0.15s, color 0.15s; + transition: + background 0.15s, + color 0.15s; cursor: pointer; } .menu-btn.active { diff --git a/composables/useApi.ts b/composables/useApi.ts index 9194c08..582dad5 100644 --- a/composables/useApi.ts +++ b/composables/useApi.ts @@ -1,33 +1,45 @@ -import { useFetch, useRuntimeConfig } from '#imports'; +import { useRuntimeConfig } from "#imports"; +import { useUserStore } from "~/stores/user"; -export const useApi = ( +export const useApi = async ( path: string, options: { - method?: 'get' | 'post' | 'put' | 'delete' - body?: any - query?: Record - headers?: HeadersInit - server?: boolean // ← 이 줄 추가! + method?: "get" | "post" | "put" | "delete"; + body?: any; + query?: Record; + headers?: HeadersInit; } = {} -) => { +): Promise => { const userStore = useUserStore(); - const config = useRuntimeConfig(); - const method = options.method ? options.method.toUpperCase() : 'GET' - - return useFetch(() => `${config.public.apiBase}${config.public.contextPath}${path}`, { - method: method as any, // 타입 강제 우회 - body: options.body, - query: options.query, - headers: { - Authorization: 'Bearer ' + userStore.getToken, - ...options.headers, - }, - onResponse({response}){ - const accessToken = response.headers.get("Authorization") || ""; - userStore.setToken(accessToken.replace("Bearer ", "")); - }, - server: options.server // ← 이 줄 추가! - }) -} \ No newline at end of file + const method = options.method ? options.method.toUpperCase() : "GET"; + + try { + const response = await $fetch( + `${config.public.apiBase}${config.public.contextPath}${path}`, + { + method: method as any, + body: options.body, + query: options.query, + headers: { + Authorization: "Bearer " + userStore.token, + ...options.headers, + }, + onResponse({ response }) { + const authHeader = response.headers.get("Authorization"); + + if (authHeader && authHeader.startsWith("Bearer ")) { + const accessToken = authHeader.substring(7); + userStore.setToken(accessToken); + } + }, + } + ); + + return response; + } catch (error) { + console.error("API 호출 실패:", error); + throw error; + } +}; diff --git a/pages/[tabId]/index.vue b/pages/[tabId]/index.vue index ec7dc4c..1672772 100644 --- a/pages/[tabId]/index.vue +++ b/pages/[tabId]/index.vue @@ -19,7 +19,7 @@

안녕하세요, {{ - userStore.userName + userStore.user?.name }}님!

@@ -28,7 +28,15 @@ 로그인되었습니다.

- +

{ // 상태 const isLoggedIn = ref(false); const user = ref<{ - id?: string; userId?: string; - email?: string; name?: string; - role?: string; } | null>(null); const token = ref(null); + // 추후 제거 필요 + const isAdmin = true; interface LoginData { - userId: string - role: string - lastLoginAt: string + userId: string; } - - // 게터 - const isAdmin = computed(() => user.value?.role === "admin"); - const userName = computed(() => user.value?.name || "사용자"); // 액션 const login = async (userId: string, password: string) => { try { // 실제 API 호출로 대체할 수 있습니다 - - const {data, error: _error } = await useApi>('/login', { - method: 'post', - body: { userId, password } - }) - let mockUser; + const { success, data } = await useApi>("/login", { + method: "post", + body: { userId, password }, + }); - if(data && data.value && data.value.success){ - mockUser = data.value.data; - }else{ + if (success) { + console.log(data); + user.value = data; + isLoggedIn.value = true; + } else { throw new Error("아이디 또는 비밀번호가 올바르지 않습니다."); } - user.value = mockUser; - // token.value = "mock-token-" + Date.now(); - isLoggedIn.value = true; - - return { success: true, user: mockUser }; - } catch (error) { - console.error("로그인 실패:", error); + return { success }; + } catch (error: any) { + console.log(error); return { success: false, error: - error instanceof Error ? error.message : "로그인에 실패했습니다.", + error?.response?.status === 401 + ? "아이디 또는 비밀번호가 올바르지 않습니다." + : error instanceof Error + ? error.message + : "로그인에 실패했습니다.", }; } }; @@ -75,13 +68,13 @@ export const useUserStore = defineStore("user", () => { } }; - const setToken = (accessToken : string) => { + const setToken = (accessToken: string) => { token.value = accessToken; - } + }; const getToken = () => { return token; - } + }; // 초기 인증 상태 확인 if (import.meta.client) { @@ -96,13 +89,12 @@ export const useUserStore = defineStore("user", () => { // 게터 isAdmin, - userName, // 액션 login, logout, checkAuth, setToken, - getToken + getToken, }; });