diff --git a/src/apis/domains/users/queries.ts b/src/apis/domains/users/queries.ts
index 18c842a8..d21ffea9 100644
--- a/src/apis/domains/users/queries.ts
+++ b/src/apis/domains/users/queries.ts
@@ -23,10 +23,10 @@ export const usePostKakaoLogin = () => {
const userData = response;
if (userData) {
- const { accessToken, nickname, role } = userData;
+ const { accessToken, nickname, refreshToken, role } = userData;
if (accessToken && nickname) {
- setUserData({ nickname, accessToken, role });
+ setUserData({ nickname, accessToken, refreshToken, role });
} else {
console.error("accessToken or nickname is undefined");
}
diff --git a/src/routes/AuthRequierd.tsx b/src/routes/AuthRequierd.tsx
new file mode 100644
index 00000000..60eb1c00
--- /dev/null
+++ b/src/routes/AuthRequierd.tsx
@@ -0,0 +1,77 @@
+import { get, instance } from "@apis/index";
+import { AxiosResponse } from "axios";
+import React, { useEffect } from "react";
+import { useNavigate } from "react-router-dom";
+import useModal from "src/hooks/useModal";
+
+interface AuthRequiredProps {
+ children: React.ReactNode;
+}
+
+const AuthRequired = ({ children }: AuthRequiredProps) => {
+ const navigate = useNavigate();
+
+ const { openAlert } = useModal();
+
+ useEffect(() => {
+ const user = localStorage.getItem("user");
+
+ if (!user || !JSON.parse(user)?.refreshToken) {
+ localStorage.clear();
+ openAlert({ title: "다시 로그인 해주세요." });
+ navigate("/auth");
+ return;
+ }
+
+ const interceptor = instance.interceptors.response.use(
+ (response) => response,
+ async (error) => {
+ const originalConfig = error.config;
+ const status = error.response?.status;
+ const msg = error.response?.data?.message;
+
+ if (status === 401) {
+ try {
+ const refreshToken = JSON.parse(user)?.refreshToken;
+
+ const response: AxiosResponse<{ data: { accessToken: string } }> = await get(
+ "/users/refresh-token",
+ {
+ headers: { Authorization_Refresh: refreshToken },
+ }
+ );
+
+ const newAccessToken = response.data?.data?.accessToken;
+
+ if (newAccessToken) {
+ localStorage.setItem("accessToken", `Bearer ${newAccessToken}`);
+ originalConfig.headers["Authorization"] = `Bearer ${newAccessToken}`;
+ return instance(originalConfig); // 기존 요청 재시도
+ }
+ throw new Error("Failed to refresh access token");
+ } catch (refreshError) {
+ console.error("Token refresh failed:", refreshError);
+ localStorage.clear();
+ openAlert({ title: "장시간 미활동으로 인해 \n자동으로 로그아웃 되었습니다." });
+ navigate("/auth");
+ window.location.reload();
+ }
+ } else if (status === 500) {
+ openAlert({
+ title: "서버에 문제가 발생했습니다. 잠시 후 다시 시도해주세요.",
+ });
+ }
+
+ return Promise.reject(error);
+ }
+ );
+
+ return () => {
+ instance.interceptors.response.eject(interceptor);
+ };
+ }, [navigate, openAlert]);
+
+ return <>{children}>;
+};
+
+export default AuthRequired;
diff --git a/src/routes/Router.tsx b/src/routes/Router.tsx
index 44115650..538f5328 100644
--- a/src/routes/Router.tsx
+++ b/src/routes/Router.tsx
@@ -1,32 +1,35 @@
-import Layout from "@components/layout/Layout";
+import Admin from "@admin/pages/admin/Admin";
+import AdminNotFound from "@admin/pages/adminNotFound/AdminNotFound";
import AdminLayout from "@components/layout/AdminLayout";
+import Layout from "@components/layout/Layout";
import Intro from "@pages/intro/Intro";
import KakaoAuth from "@pages/kakaoAuth/KakaoAuth";
import Main from "@pages/main/Main";
import NotFound from "@pages/notFound/NotFound";
-import AdminNotFound from "@admin/pages/adminNotFound/AdminNotFound";
import OnBoarding from "@pages/onBoarding/OnBoarding";
import { GIG_ROUTES, LOOKUP_ROUTES, MANAGE_ROUTES, REGISTER_ROUTES, TEST_ROUTES } from "@routes";
+import DesktopGlobalStyle from "@styles/desktop";
import { createBrowserRouter } from "react-router-dom";
import ADMIN_ROUTES from "./AdminRoutes";
-import Admin from "@admin/pages/admin/Admin";
-import DesktopGlobalStyle from "@styles/desktop";
-import TokenRefresher from "src/hooks/useTokenRefresher";
+import AuthRequired from "./AuthRequierd";
const router = createBrowserRouter([
{
path: "/main",
element: (
- <>
-
+
- >
+
),
},
{ path: "/intro", element: },
{
path: "/",
- element: ,
+ element: (
+
+
+
+ ),
children: [
{ path: "", element: },
...GIG_ROUTES,
diff --git a/src/stores/user.ts b/src/stores/user.ts
index 46a37d1b..bbdfc810 100644
--- a/src/stores/user.ts
+++ b/src/stores/user.ts
@@ -4,5 +4,6 @@ import { atomWithStorage } from "jotai/utils";
export const userAtom = atomWithStorage("user", {
nickname: "",
accessToken: "",
+ refreshToken: "",
role: "",
});
diff --git a/src/typings/userType.ts b/src/typings/userType.ts
index ea90a66e..9dcac8a3 100644
--- a/src/typings/userType.ts
+++ b/src/typings/userType.ts
@@ -1,5 +1,6 @@
export interface UserProps {
nickname: string;
accessToken: string;
+ refreshToken: string;
role: string;
}