diff --git a/.yarn/cache/@esbuild-darwin-x64-npm-0.17.19-30afb0190b-8.zip b/.yarn/cache/@esbuild-darwin-x64-npm-0.17.19-30afb0190b-8.zip deleted file mode 100644 index ce0c4aa9..00000000 Binary files a/.yarn/cache/@esbuild-darwin-x64-npm-0.17.19-30afb0190b-8.zip and /dev/null differ diff --git a/.yarn/cache/@esbuild-darwin-x64-npm-0.18.13-e38db97cb2-8.zip b/.yarn/cache/@esbuild-darwin-x64-npm-0.18.13-e38db97cb2-8.zip deleted file mode 100644 index f29465c7..00000000 Binary files a/.yarn/cache/@esbuild-darwin-x64-npm-0.18.13-e38db97cb2-8.zip and /dev/null differ diff --git a/.yarn/cache/@next-swc-darwin-x64-npm-13.5.6-3c6ecf4082-8.zip b/.yarn/cache/@next-swc-darwin-x64-npm-13.5.6-3c6ecf4082-8.zip deleted file mode 100644 index 0dfaf447..00000000 Binary files a/.yarn/cache/@next-swc-darwin-x64-npm-13.5.6-3c6ecf4082-8.zip and /dev/null differ diff --git a/@types/next-auth.d.ts b/@types/next-auth.d.ts new file mode 100644 index 00000000..0a064c61 --- /dev/null +++ b/@types/next-auth.d.ts @@ -0,0 +1,13 @@ +import NextAuth, { DefaultSession } from 'next-auth'; + +declare module 'next-auth' { + /** + * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context + */ + interface Session { + user: { + accessToken: string; + tokenType: string; + } & DefaultSession['user']; + } +} diff --git a/src/components/auth/AuthProvider.tsx b/src/components/auth/AuthProvider.tsx deleted file mode 100644 index 1d7faf2d..00000000 --- a/src/components/auth/AuthProvider.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { type ReactNode, useEffect } from 'react'; -import { useSession } from 'next-auth/react'; -import { useSetAtom } from 'jotai'; - -import { LOCAL_STORAGE_KEY } from '~/constants/storage'; -import { post } from '~/libs/api'; -import { isUserTokenValidAtom } from '~/store/auth'; - -interface Props { - children: ReactNode; -} - -const AuthProvider = ({ children }: Props) => { - const { data, status } = useSession(); - const setIsUserTokenValid = useSetAtom(isUserTokenValidAtom); - - useEffect(() => { - if (!data) return; - if (status !== 'authenticated') return; - - const getToken = async () => { - const token = await post('/v1/oauth/kakao', { - nickname: data?.user?.name, - email: data?.user?.email, - }); - - return token; - }; - - const setToken = async () => { - const token = await getToken(); - setIsUserTokenValid(true); - localStorage.setItem(LOCAL_STORAGE_KEY.accessToken, token.access_token); - }; - - setToken(); - }, [data, status]); - - return <>{children}; -}; - -export default AuthProvider; - -interface Token { - token_type: string; - access_token: string; -} diff --git a/src/components/auth/AuthSessionLoader.tsx b/src/components/auth/AuthSessionLoader.tsx new file mode 100644 index 00000000..849570b1 --- /dev/null +++ b/src/components/auth/AuthSessionLoader.tsx @@ -0,0 +1,26 @@ +import { type ReactNode, useLayoutEffect } from 'react'; +import { useSession } from 'next-auth/react'; +import { useSetAtom } from 'jotai'; + +import { LOCAL_STORAGE_KEY } from '~/constants/storage'; +import { isUserTokenValidAtom } from '~/store/auth'; + +interface Props { + children: ReactNode; +} + +const AuthSessionLoader = ({ children }: Props) => { + const { data, status } = useSession(); + const setIsUserTokenValid = useSetAtom(isUserTokenValidAtom); + + useLayoutEffect(() => { + if (status !== 'authenticated') return; + + setIsUserTokenValid(true); + localStorage.setItem(LOCAL_STORAGE_KEY.accessToken, data.user.accessToken); + }, [data, setIsUserTokenValid, status]); + + return <>{children}; +}; + +export default AuthSessionLoader; diff --git a/src/components/sideMenu/MenuSection.tsx b/src/components/sideMenu/MenuSection.tsx index 19399516..0c67f608 100644 --- a/src/components/sideMenu/MenuSection.tsx +++ b/src/components/sideMenu/MenuSection.tsx @@ -25,7 +25,7 @@ function MenuSection() { label: '로그아웃', action: () => { // 실 환경에서 되는지 체크 - logOutHandler(); + logOutHandler({ callbackUrl: '/' }); router.replace('/'); }, }, diff --git a/src/features/home/KakaoLoginButton.tsx b/src/features/home/KakaoLoginButton.tsx index d64879a9..bdac7f0d 100644 --- a/src/features/home/KakaoLoginButton.tsx +++ b/src/features/home/KakaoLoginButton.tsx @@ -13,7 +13,7 @@ const KakaoLoginButton = () => { if (status === 'authenticated') { return (
-
@@ -23,7 +23,7 @@ const KakaoLoginButton = () => { return (
이미 질문폼이 있다면? -
diff --git a/src/hooks/auth/useKakaoLogin.tsx b/src/hooks/auth/useKakaoLogin.tsx index c35340b4..42ded335 100644 --- a/src/hooks/auth/useKakaoLogin.tsx +++ b/src/hooks/auth/useKakaoLogin.tsx @@ -1,18 +1,16 @@ -import { signIn, signOut, useSession } from 'next-auth/react'; +import { signIn, type SignInOptions, signOut, type SignOutParams, useSession } from 'next-auth/react'; import { LOCAL_STORAGE_KEY } from '~/constants/storage'; const useKakaoLogin = () => { const { status } = useSession(); - const logOutHandler = () => { - signOut(); + const logOutHandler = (options?: SignOutParams) => { localStorage.removeItem(LOCAL_STORAGE_KEY.accessToken); + signOut(options); }; - const loginHandler = () => { - signIn('kakao'); - }; + const loginHandler = (options?: SignInOptions) => signIn('kakao', options); return { logOutHandler, diff --git a/src/pages/_app.page.tsx b/src/pages/_app.page.tsx index 88aaca72..0e3c0710 100644 --- a/src/pages/_app.page.tsx +++ b/src/pages/_app.page.tsx @@ -10,7 +10,7 @@ import { Analytics } from '@vercel/analytics/react'; import { domMax, LazyMotion } from 'framer-motion'; import { useOpenExternalBrowser } from 'open-external-browser'; -import AuthProvider from '~/components/auth/AuthProvider'; +import AuthSessionLoader from '~/components/auth/AuthSessionLoader'; import ErrorBoundary from '~/components/error/ErrorBoundary'; import MonitoringInitializer from '~/components/monitoring/MonitoringInitializer'; import NewFeedbackSnackBarListener from '~/components/snackBar/NewFeedbackSnackBarListener'; @@ -55,14 +55,14 @@ export default function App({ Component, pageProps }: AppPropsWithLayout) { return ( - - - - - - - - + + + + + + + +
{getLayout()} @@ -71,13 +71,13 @@ export default function App({ Component, pageProps }: AppPropsWithLayout) {
-
-
-
-
- -
-
+ + + + + + +
); } diff --git a/src/pages/api/auth/[...nextauth].api.ts b/src/pages/api/auth/[...nextauth].api.ts index 2b0e62d2..b6b14832 100644 --- a/src/pages/api/auth/[...nextauth].api.ts +++ b/src/pages/api/auth/[...nextauth].api.ts @@ -2,7 +2,26 @@ import NextAuth from 'next-auth'; import CredentialsProvider from 'next-auth/providers/credentials'; import KakaoProvider from 'next-auth/providers/kakao'; +import { post } from '~/libs/api'; + +interface TokenResponse { + token_type: string; + access_token: string; +} + export default NextAuth({ + callbacks: { + session: async ({ session, token }) => { + const jwtTokenFromNaLabServer = await post('/v1/oauth/kakao', { + nickname: token.name, + email: token.email, + }); + session.user.accessToken = jwtTokenFromNaLabServer.access_token; + session.user.tokenType = jwtTokenFromNaLabServer.token_type; + + return session; + }, + }, providers: [ process.env.CLOUDFLARE_ENV === 'preview' ? CredentialsProvider({ diff --git a/src/pages/gallery/index.page.tsx b/src/pages/gallery/index.page.tsx index 22737b87..2c8ac8ff 100644 --- a/src/pages/gallery/index.page.tsx +++ b/src/pages/gallery/index.page.tsx @@ -2,7 +2,6 @@ import { useState } from 'react'; import Link from 'next/link'; import { css } from '@emotion/react'; -import BottomBar from '~/components/bottomBar/BottomBar'; import Header from '~/components/header/MobileHeader'; import StaggerWrapper from '~/components/stagger/StaggerWrapper'; import Card from '~/features/gallery/Card'; @@ -53,7 +52,7 @@ function Gallery() { /> )} - + {/* */} ); } diff --git a/src/pages/survey/create.page.tsx b/src/pages/survey/create.page.tsx index a4b54bce..c6c0d996 100644 --- a/src/pages/survey/create.page.tsx +++ b/src/pages/survey/create.page.tsx @@ -2,7 +2,6 @@ import { useSession } from 'next-auth/react'; import { css, type Theme } from '@emotion/react'; import { useAtom, useAtomValue } from 'jotai'; -import BottomBar from '~/components/bottomBar/BottomBar'; import CTAButton from '~/components/button/CTAButton'; import Header from '~/components/header/Header'; import SEO from '~/components/SEO/SEO'; @@ -83,7 +82,7 @@ const CreateSurveyPage = () => { - + {/* */} ); diff --git a/src/pages/survey/join.page.tsx b/src/pages/survey/join.page.tsx index b931768f..5c460a64 100644 --- a/src/pages/survey/join.page.tsx +++ b/src/pages/survey/join.page.tsx @@ -103,7 +103,7 @@ const JoinGuidePage = () => { - + loginHandler()}> 카카오 계정으로 회원가입 하기 diff --git a/src/store/auth.ts b/src/store/auth.ts index 6ab8e242..96b06dff 100644 --- a/src/store/auth.ts +++ b/src/store/auth.ts @@ -1,3 +1,4 @@ import { atom } from 'jotai'; +// TODO: 이거 삭제 export const isUserTokenValidAtom = atom(false);