Skip to content

Commit

Permalink
Merge pull request TEAM-BEAT#465 from TEAM-BEAT/refactor/TEAM-BEAT#464/…
Browse files Browse the repository at this point in the history
…refresh-token

Refactor/TEAM-BEAT#464/refresh token
  • Loading branch information
pepperdad authored Dec 18, 2024
2 parents ec96d41 + 80bffe8 commit 8c46b30
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/apis/domains/users/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
77 changes: 77 additions & 0 deletions src/routes/AuthRequierd.tsx
Original file line number Diff line number Diff line change
@@ -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;
21 changes: 12 additions & 9 deletions src/routes/Router.tsx
Original file line number Diff line number Diff line change
@@ -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: (
<>
<TokenRefresher />
<AuthRequired>
<Main />
</>
</AuthRequired>
),
},
{ path: "/intro", element: <Intro /> },
{
path: "/",
element: <Layout />,
element: (
<AuthRequired>
<Layout />
</AuthRequired>
),
children: [
{ path: "", element: <OnBoarding /> },
...GIG_ROUTES,
Expand Down
1 change: 1 addition & 0 deletions src/stores/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ import { atomWithStorage } from "jotai/utils";
export const userAtom = atomWithStorage<UserProps>("user", {
nickname: "",
accessToken: "",
refreshToken: "",
role: "",
});
1 change: 1 addition & 0 deletions src/typings/userType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export interface UserProps {
nickname: string;
accessToken: string;
refreshToken: string;
role: string;
}

0 comments on commit 8c46b30

Please sign in to comment.