From 2db519478b4105871857eb928eb90ac93e721d2a Mon Sep 17 00:00:00 2001 From: bytrustu Date: Sun, 9 Jul 2023 03:05:15 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20AuthProvider=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/app/layout.tsx | 9 ++- apps/client/src/components/index.ts | 1 + .../src/components/provider/AuthProvider.tsx | 59 +++++++++++++++++++ apps/client/src/components/provider/index.ts | 5 ++ apps/client/src/constant/index.ts | 1 + apps/client/src/constant/pageUrl.ts | 4 ++ libs/lib/src/constants/tokenKey.ts | 3 +- libs/lib/src/utils/storage.ts | 21 ++++--- 8 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 apps/client/src/components/provider/AuthProvider.tsx create mode 100644 apps/client/src/components/provider/index.ts create mode 100644 apps/client/src/constant/pageUrl.ts diff --git a/apps/client/app/layout.tsx b/apps/client/app/layout.tsx index 9721660..1e58084 100644 --- a/apps/client/app/layout.tsx +++ b/apps/client/app/layout.tsx @@ -1,6 +1,7 @@ import './global.css'; import { PropsWithChildren } from 'react'; import { Layout, OverlayProvider, ReactQueryProvider } from '@oseek/ui'; +import { AuthProvider } from '@components/provider'; export const metadata = { title: { @@ -14,9 +15,11 @@ export default function RootLayout({ children }: PropsWithChildren) { - - {children} - + + + {children} + + diff --git a/apps/client/src/components/index.ts b/apps/client/src/components/index.ts index 0b7df71..37206e5 100644 --- a/apps/client/src/components/index.ts +++ b/apps/client/src/components/index.ts @@ -9,6 +9,7 @@ export * from './layout/index'; export * from './location/index'; export * from './login/index'; export * from './main/index'; +export * from './provider/index'; export * from './section/index'; export * from './shop/index'; export * from './spacing/index'; diff --git a/apps/client/src/components/provider/AuthProvider.tsx b/apps/client/src/components/provider/AuthProvider.tsx new file mode 100644 index 0000000..2fa0a01 --- /dev/null +++ b/apps/client/src/components/provider/AuthProvider.tsx @@ -0,0 +1,59 @@ +'use client'; + +import React, { createContext, useState, useEffect, useContext, PropsWithChildren } from 'react'; +import { useRouter } from 'next/navigation'; +import { + ACCESS_TOKEN_KEY, + REFRESH_TOKEN_KEY, + USER_KEY, + removeLocalStorageItem, + getAccessTokenByLocalStorage, + getRefreshTokenByLocalStorage, + getUserByLocalStorage, + UserType, +} from '@oseek/lib'; +import { PAGE_URL } from '@constant/pageUrl'; + +interface AuthContextProps { + user: UserType | null; + isLoggedIn: boolean; + logout: () => void; +} + +const AuthContext = createContext(undefined); + +export const AuthProvider = ({ children }: PropsWithChildren) => { + const router = useRouter(); + const [user, setUser] = useState(null); + + const logout = () => { + setUser(null); + removeLocalStorageItem(ACCESS_TOKEN_KEY); + removeLocalStorageItem(REFRESH_TOKEN_KEY); + removeLocalStorageItem(USER_KEY); + router.replace(PAGE_URL.MAIN); + }; + + const isLoggedIn = () => { + const accessToken = getAccessTokenByLocalStorage(); + const refreshToken = getRefreshTokenByLocalStorage(); + return user !== null && accessToken !== null && refreshToken !== null; + }; + + useEffect(() => { + const storedUser = getUserByLocalStorage(); + if (storedUser) { + setUser(storedUser); + } + }, []); + + return {children}; +}; + +export const useAuth = (): AuthContextProps => { + const context = useContext(AuthContext); + if (!context) { + throw new Error('useAuth를 사용하려면 AuthProvider를 상위에 제공해야 합니다.'); + } + return context; +}; diff --git a/apps/client/src/components/provider/index.ts b/apps/client/src/components/provider/index.ts new file mode 100644 index 0000000..5a24ddb --- /dev/null +++ b/apps/client/src/components/provider/index.ts @@ -0,0 +1,5 @@ +/** + * @file Automatically generated by barrelsby. + */ + +export * from './AuthProvider'; diff --git a/apps/client/src/constant/index.ts b/apps/client/src/constant/index.ts index cbcf0a9..526e2ba 100644 --- a/apps/client/src/constant/index.ts +++ b/apps/client/src/constant/index.ts @@ -3,3 +3,4 @@ */ export * from './foodKeyword'; +export * from './pageUrl'; diff --git a/apps/client/src/constant/pageUrl.ts b/apps/client/src/constant/pageUrl.ts new file mode 100644 index 0000000..5046464 --- /dev/null +++ b/apps/client/src/constant/pageUrl.ts @@ -0,0 +1,4 @@ +export const PAGE_URL = { + MAIN: '/', + SETTING_NAME: '/login/setting-name', +}; diff --git a/libs/lib/src/constants/tokenKey.ts b/libs/lib/src/constants/tokenKey.ts index bb12ce9..bf71961 100644 --- a/libs/lib/src/constants/tokenKey.ts +++ b/libs/lib/src/constants/tokenKey.ts @@ -1,4 +1,3 @@ export const ACCESS_TOKEN_KEY = 'accessToken'; export const REFRESH_TOKEN_KEY = 'refreshToken'; -export const NICKNAME_KEY = 'nickname'; -export const LOCATION_KEY = 'location'; +export const USER_KEY = 'user'; diff --git a/libs/lib/src/utils/storage.ts b/libs/lib/src/utils/storage.ts index b3bf2fc..9ff7cae 100644 --- a/libs/lib/src/utils/storage.ts +++ b/libs/lib/src/utils/storage.ts @@ -1,4 +1,5 @@ -import { ACCESS_TOKEN_KEY, LOCATION_KEY, NICKNAME_KEY, REFRESH_TOKEN_KEY } from '../constants'; +import { ACCESS_TOKEN_KEY, REFRESH_TOKEN_KEY, USER_KEY } from '../constants'; +import { MemberInfoResDto } from '@oseek/apis'; export const getLocalStorageItem = (key: string): T | null => { if (typeof window !== 'undefined') { @@ -28,6 +29,12 @@ export const setLocalStorageItem = (key: string, value: T): void => { } }; +export const removeLocalStorageItem = (key: string): void => { + if (typeof window !== 'undefined') { + localStorage.removeItem(key); + } +}; + export const getAccessTokenByLocalStorage = (): string | null => { const accessToken = getLocalStorageItem(ACCESS_TOKEN_KEY); return accessToken || null; @@ -38,12 +45,8 @@ export const getRefreshTokenByLocalStorage = (): string | null => { return refreshToken || null; }; -export const getNickNameByLocalStorage = (): string | null => { - const nickname = getLocalStorageItem(NICKNAME_KEY); - return nickname || null; -}; - -export const getLocationByLocalStorage = (): string | null => { - const location = getLocalStorageItem(LOCATION_KEY); - return location || null; +export type UserType = Pick; +export const getUserByLocalStorage = (): UserType | null => { + const user = getLocalStorageItem(USER_KEY); + return user || null; };