diff --git a/components/AuthProvider.tsx b/components/AuthProvider.tsx
index 0357270..075c854 100644
--- a/components/AuthProvider.tsx
+++ b/components/AuthProvider.tsx
@@ -11,10 +11,13 @@ const AuthProvider = ({ children }: { children: React.ReactNode }) => {
const { refresh } = useAuth();
useEffect(() => {
+ // refresh 여부를 알 수 있는 코드, 당장은 필요 없으나 이후 의도치 않은 refresh가 계속 발생할 경우 사용
+ // const entries = performance.getEntriesByType('navigation')[0];
+ // const entriesNavigationTiming = entries as PerformanceNavigationTiming;
+ // entriesNavigationTiming.type === 'reload'
+
const refreshToken = localStorage.getItem('refreshToken');
- if (!isAuthorized && refreshToken) {
- refresh(refreshToken as string);
- }
+ if (!isAuthorized && refreshToken) refresh(refreshToken as string);
}, [isAuthorized, refresh]);
return
{children}
;
diff --git a/components/withAuth.tsx b/components/withAuth.tsx
new file mode 100644
index 0000000..3ddf50c
--- /dev/null
+++ b/components/withAuth.tsx
@@ -0,0 +1,32 @@
+'use client';
+
+import { useRouter } from 'next/navigation';
+import { useEffect } from 'react';
+import { useAuthStore } from '@/stores/authStore';
+
+export interface WithAuthProps {} // 추후에 인증 과정에 더 필요한 props를 위해
+
+export default function withAuth(
+ Component: React.ComponentType,
+) {
+ const ComponentWithAuth = (props: Omit) => {
+ const isAuthorized = useAuthStore((state) => state.authInfo.isAuthorized);
+ const isLoading = useAuthStore((state) => state.authInfo.isLoading);
+ const router = useRouter();
+
+ useEffect(() => {
+ // 가장 초기 상태에는 undefined이므로, 해당 경우를 고려 해주어야 함
+ if (isLoading !== undefined && !isLoading && !isAuthorized) {
+ router.push('/login');
+ }
+ });
+
+ return !isLoading && isAuthorized ? (
+
+ ) : (
+ loading
// 렌더링과 라우팅 사이의 딜레이 시 보여질 화면
+ );
+ };
+
+ return ComponentWithAuth;
+}
diff --git a/hooks/auth.ts b/hooks/auth.ts
index f45ba71..564bea8 100644
--- a/hooks/auth.ts
+++ b/hooks/auth.ts
@@ -7,6 +7,7 @@ export const useAuth = () => {
const setAuthInfo = useAuthStore((state) => state.setAuthInfo);
const login = async (provider: string, code: string) => {
+ setAuthInfo({ isLoading: true });
const res = await fetch(
`${process.env.NEXT_PUBLIC_SERVER_BASE_URL}/v1/login/${provider}?code=${code}`,
{ cache: 'no-store' },
@@ -15,13 +16,15 @@ export const useAuth = () => {
if (res.ok) {
const result: TAuthInfo = await res.json();
localStorage.setItem('refreshToken', result.refreshToken as string);
- setAuthInfo(result);
+ setAuthInfo({ ...result, isAuthorized: true, isLoading: false });
return result;
}
+ setAuthInfo(null);
return false;
};
const refresh = async (token: string) => {
+ setAuthInfo({ isLoading: true });
const headers = new Headers();
headers.set('Authorization', `Bearer ${token}`);
const res = await fetch(
@@ -31,8 +34,8 @@ export const useAuth = () => {
if (res.ok) {
const result: TAuthInfo = await res.json();
localStorage.setItem('refreshToken', result.refreshToken as string);
- setAuthInfo(result);
- return res.json();
+ setAuthInfo({ ...result, isAuthorized: true, isLoading: false });
+ return result;
}
localStorage.removeItem('refreshToken');
setAuthInfo(null);
@@ -40,6 +43,7 @@ export const useAuth = () => {
};
const logout = async (provider: string, token: string) => {
+ setAuthInfo({ isLoading: true });
const headers = new Headers();
headers.set('Authorization', `bearer ${token}`);
const res = await fetch(
@@ -52,6 +56,7 @@ export const useAuth = () => {
setAuthInfo(null);
return true;
}
+ setAuthInfo({ isLoading: false });
return false;
};
diff --git a/stores/authStore.tsx b/stores/authStore.tsx
index aed46fc..a52d72a 100644
--- a/stores/authStore.tsx
+++ b/stores/authStore.tsx
@@ -10,6 +10,7 @@ interface TUseAuth {
const initialState: TAuthInfo = {
isAuthorized: false,
+ isLoading: false,
id: null,
nickName: null,
email: null,
@@ -23,9 +24,7 @@ export const useAuthStore = create(
authInfo: initialState,
setAuthInfo: (payload) =>
set((state) => ({
- authInfo: payload
- ? { ...state.authInfo, ...payload, isAuthorized: true }
- : initialState,
+ authInfo: payload ? { ...state.authInfo, ...payload } : initialState,
})),
})),
);
diff --git a/types/index.ts b/types/index.ts
index 9ee6c07..2ba566d 100644
--- a/types/index.ts
+++ b/types/index.ts
@@ -28,6 +28,7 @@ export interface TQna {
}
export interface TAuthInfo {
+ isLoading: boolean;
isAuthorized: boolean;
id: number | null;
nickName: string | null;