diff --git a/src/apis/auth.ts b/src/apis/auth.ts index 2a62689..ee013dc 100644 --- a/src/apis/auth.ts +++ b/src/apis/auth.ts @@ -1,3 +1,4 @@ +import axiosInstance from "@/apis/config/instance"; import { apiPost } from "@/lib/api"; import { API_ENDPOINTS } from "./config/endpoints"; @@ -8,6 +9,31 @@ interface LogoutResponse { data: string; } +export interface CheckLoginResponse { + success: boolean; + code: number; + message: string; + data: { + validUser: boolean; + invalidToken: boolean; + owner: boolean; + }; +} + export const logout = async (): Promise => { return apiPost(API_ENDPOINTS.AUTH.LOGOUT); }; + +export const checkLogin = async ( + shareUri: string +): Promise => { + const response = await axiosInstance.post( + API_ENDPOINTS.AUTH.CHECK_LOGIN, + null, + { + params: { shareUri }, + headers: { skipAuthRedirect: "true" }, + } + ); + return response.data; +}; diff --git a/src/apis/config/endpoints.ts b/src/apis/config/endpoints.ts index d0f41b0..2957568 100644 --- a/src/apis/config/endpoints.ts +++ b/src/apis/config/endpoints.ts @@ -9,6 +9,7 @@ export const API_ENDPOINTS = { AUTH: { REISSUE: "/auth/reissue", LOGOUT: "/auth/logout", + CHECK_LOGIN: "/auth/check-login", }, // 시간 관련 diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx index 26620ef..4065c26 100644 --- a/src/components/ui/sidebar.tsx +++ b/src/components/ui/sidebar.tsx @@ -30,7 +30,9 @@ export function Sidebar({ isLoggedIn, isCheckingAuth, hasFetchedAuth, + lastCheckedShareUri, checkAuth, + checkAuthForSharedBoard, reset: resetAuth, } = useAuthStore(); @@ -44,11 +46,26 @@ export function Sidebar({ const isSharedBoard = Boolean(shareUri); useEffect(() => { - // 공유 보드가 아닌 경우에만 인증 체크 - if (!isSharedBoard && !hasFetchedAuth && !isCheckingAuth) { + if (isCheckingAuth) return; + + if (isSharedBoard && shareUri) { + // 공유 보드 + if (lastCheckedShareUri !== shareUri) { + void checkAuthForSharedBoard(shareUri); + } + } else if (!hasFetchedAuth) { + // 내 보드 void checkAuth(); } - }, [isSharedBoard, checkAuth, hasFetchedAuth, isCheckingAuth]); + }, [ + isSharedBoard, + shareUri, + checkAuth, + checkAuthForSharedBoard, + hasFetchedAuth, + lastCheckedShareUri, + isCheckingAuth, + ]); const handleLogoutClick = () => { setShowLogoutAlert(true); diff --git a/src/stores/useAuthStore.ts b/src/stores/useAuthStore.ts index 416aee9..8b394f8 100644 --- a/src/stores/useAuthStore.ts +++ b/src/stores/useAuthStore.ts @@ -1,4 +1,5 @@ import { create } from "zustand"; +import { checkLogin, type CheckLoginResponse } from "@/apis/auth"; import { getBoardShareForAuth } from "@/apis/board"; import type { GetBoardShareResponse } from "@/types/board"; @@ -6,10 +7,15 @@ interface AuthState { isLoggedIn: boolean; isCheckingAuth: boolean; hasFetchedAuth: boolean; + lastCheckedShareUri: string | null; boardShare: GetBoardShareResponse["data"] | null; checkAuth: (options?: { force?: boolean; }) => Promise; + checkAuthForSharedBoard: ( + shareUri: string, + options?: { force?: boolean } + ) => Promise; setLoggedIn: ( value: boolean, options?: { boardShare?: GetBoardShareResponse["data"] | null } @@ -21,6 +27,7 @@ export const useAuthStore = create((set, get) => ({ isLoggedIn: false, isCheckingAuth: false, hasFetchedAuth: false, + lastCheckedShareUri: null, boardShare: null, checkAuth: async ({ force = false } = {}) => { @@ -55,6 +62,39 @@ export const useAuthStore = create((set, get) => ({ } }, + checkAuthForSharedBoard: async (shareUri: string, { force = false } = {}) => { + const { lastCheckedShareUri } = get(); + + // 같은 shareUri로 이미 체크했으면 스킵 (force가 아닌 경우) + if (lastCheckedShareUri === shareUri && !force) { + return null; + } + + set({ isCheckingAuth: true }); + + try { + const response = await checkLogin(shareUri); + + set({ + isLoggedIn: response.data.validUser, + isCheckingAuth: false, + hasFetchedAuth: true, + lastCheckedShareUri: shareUri, + }); + + return response.data; + } catch { + set({ + isLoggedIn: false, + isCheckingAuth: false, + hasFetchedAuth: true, + lastCheckedShareUri: shareUri, + }); + + return null; + } + }, + setLoggedIn: (value: boolean, options) => { set({ isLoggedIn: value, @@ -69,6 +109,7 @@ export const useAuthStore = create((set, get) => ({ isLoggedIn: false, isCheckingAuth: false, hasFetchedAuth: true, + lastCheckedShareUri: null, boardShare: null, }); },