diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx index 24c81d4..cf83a32 100644 --- a/src/app/dashboard/layout.tsx +++ b/src/app/dashboard/layout.tsx @@ -13,7 +13,7 @@ import useDashboardStore from '@/store/useDashboardStore' * 주스탠드에 저장된 대시보드 목록에서 dashboardid 로 title 가져올 수 잇을 듯 */ export default function UserDashboardLayout({ children }: PropsWithChildren) { - useRedirect({ requireAuth: true }) + // useRedirect({ requireAuth: true }) const { id } = useParams() const { dashboards, dashboard, setDashboard } = useDashboardStore() diff --git a/src/app/login/components/LoginForm.tsx b/src/app/login/components/LoginForm.tsx index 21fcf01..696d77f 100644 --- a/src/app/login/components/LoginForm.tsx +++ b/src/app/login/components/LoginForm.tsx @@ -13,6 +13,8 @@ import { getDashboardList } from '@/lib/dashboardsApi' import useDashboardStore from '@/store/useDashboardStore' import useModalStore from '@/store/useModalStore' +import loginAction from '../loginAction' + export interface LoginFormValue { email: string password: string @@ -29,6 +31,7 @@ export default function LoginForm() { } = useForm() const router = useRouter() + const { openModal } = useModalStore() const { setDashboards } = useDashboardStore() @@ -36,23 +39,12 @@ export default function LoginForm() { const passwordType = pwdVisible ? 'text' : 'password' const onSubmit = async (data: LoginFormValue) => { - try { - const response = await api.post('auth/login', data) - const { accessToken, user } = response.data - sessionStorage.setItem('accessToken', accessToken) - sessionStorage.setItem('user', JSON.stringify(user)) - const dashboards = await getDashboardList() - setDashboards(dashboards) - router.push('/mydashboard') - } catch (error) { - let loginErrorMessage = '' - if (axios.isAxiosError(error)) { - loginErrorMessage = error.response?.data.message - } else { - loginErrorMessage = - '서버에 문제가 있는거 같아요. 잠시 후에 다시 시도해보시겠어요?' - } - openModal() + // 로그인 액션 실행 + const errMsg = await loginAction(data) + + // 에러 메시지 팝업 + if (errMsg) { + openModal() } } diff --git a/src/app/login/loginAction.tsx b/src/app/login/loginAction.tsx new file mode 100644 index 0000000..e576ac6 --- /dev/null +++ b/src/app/login/loginAction.tsx @@ -0,0 +1,29 @@ +'use server' +import { cookies } from 'next/headers' +import { redirect } from 'next/navigation' + +import api from '@/lib/axiosServer' + +import { LoginFormValue } from './components/LoginForm' + +export default async function loginAction(data: LoginFormValue) { + // 백엔드 요청 + try { + const response = await api.post('/auth/login', data, {}) + const { accessToken, user } = response.data + + // 가져온 json token 쿠키 설정 하기 + cookies().set('Authorization', accessToken, { + secure: true, + // httpOnly: true, + expires: new Date(Date.now() + 24 * 60 * 60 * 1000 * 3), + // path: '/', + sameSite: 'strict', + }) + } catch (error: any) { + return error.response?.data?.message || error.message + } + + // 로그인 여부에 따라 redirect + redirect('/mydashboard') +} diff --git a/src/app/mydashboard/page.tsx b/src/app/mydashboard/page.tsx index 0b0a2c6..bbf22fc 100644 --- a/src/app/mydashboard/page.tsx +++ b/src/app/mydashboard/page.tsx @@ -18,7 +18,7 @@ type PaginationAction = 'prev' | 'next' const ITEM_PER_PAGE = 5 export default function MyDashboard() { - useRedirect({ requireAuth: true }) + // useRedirect({ requireAuth: true }) const { openModal } = useModalStore() const { dashboards } = useDashboardStore() diff --git a/src/app/mypage/page.tsx b/src/app/mypage/page.tsx index c6b4d29..b2da594 100644 --- a/src/app/mypage/page.tsx +++ b/src/app/mypage/page.tsx @@ -7,7 +7,7 @@ import PasswordEditForm from './components/PasswordEditForm' import ProfileEditForm from './components/ProfileEditForm' export default function MyPagePage() { - useRedirect({ requireAuth: true }) + // useRedirect({ requireAuth: true }) const handleGoBack = useGoBack() diff --git a/src/app/page.tsx b/src/app/page.tsx index c7639a6..4e48ce0 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -6,7 +6,7 @@ import useRedirect from '@/hooks/useRedirect' import { Providers } from './providers' export default function Home() { - useRedirect({ requireAuth: false }) + // useRedirect({ requireAuth: false }) return ( <> diff --git a/src/app/signup/page.tsx b/src/app/signup/page.tsx index f78928d..7951d18 100644 --- a/src/app/signup/page.tsx +++ b/src/app/signup/page.tsx @@ -5,7 +5,7 @@ import useRedirect from '@/hooks/useRedirect' import AuthPageLayout from '@/layouts/AuthPageLayout' export default function SignupPage() { - useRedirect({ requireAuth: false }) + // useRedirect({ requireAuth: false }) return ( diff --git a/src/components/UserProfile.tsx b/src/components/UserProfile.tsx index ff2fd5c..a4cca4a 100644 --- a/src/components/UserProfile.tsx +++ b/src/components/UserProfile.tsx @@ -18,6 +18,7 @@ export default function UserProfile() { try { const response = await api.get('users/me') setUser(response.data) + sessionStorage.setItem('user', response.data) } catch (error) { throw error } @@ -31,6 +32,8 @@ export default function UserProfile() { router.push('/login') setUser(null) sessionStorage.clear() + + document.cookie = `Authorization=; Max-Age=-99999999;` } useEffect(() => { diff --git a/src/lib/axiosInstance.ts b/src/lib/axiosInstance.ts index 65df261..190f422 100644 --- a/src/lib/axiosInstance.ts +++ b/src/lib/axiosInstance.ts @@ -6,18 +6,21 @@ const api = axios.create({ 'Content-Type': 'application/json', }, // withCredentials: true, - // timeout: 10000, // 요청 제한 시간 설정 (밀리초) }) -let accessToken: string = '' - -export const setAccessToken = (token: string) => { - accessToken = token -} - api.interceptors.request.use( config => { - const token = sessionStorage.getItem('accessToken') + function getCookie(name: string) { + const value = `; ${document.cookie}` + const parts = value.split(`; ${name}=`) + + if (parts) { + return parts[1].split(';').shift() + } + } + + const token = getCookie('Authorization') + console.log(token) if (token) { config.headers.Authorization = `Bearer ${token}` } diff --git a/src/lib/axiosServer.ts b/src/lib/axiosServer.ts new file mode 100644 index 0000000..0adf225 --- /dev/null +++ b/src/lib/axiosServer.ts @@ -0,0 +1,29 @@ +'use server' + +import axios from 'axios' +import { cookies } from 'next/headers' + +const api = axios.create({ + baseURL: 'https://sp-taskify-api.vercel.app/7-2', + headers: { + 'Content-Type': 'application/json', + }, + withCredentials: true, +}) + +api.interceptors.request.use( + config => { + console.log('interceptor') + const token = cookies().get('Authorization') + + if (token) { + config.headers.Authorization = `Bearer ${token}` + } + return config + }, + error => { + return Promise.reject(error) + } +) + +export default api diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..f200c39 --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,19 @@ +import { cookies } from 'next/headers' +import type { NextRequest } from 'next/server' +import { NextResponse } from 'next/server' + +export async function middleware(request: NextRequest) { + // 쿠키 확인 + const cookie = cookies().get('Authorization') + if (!cookie) { + return NextResponse.redirect(new URL('/login', request.url)) + } + + if (cookie && request.nextUrl.pathname === '/') { + return NextResponse.redirect(new URL('/mydashboard', request.url)) + } +} + +export const config = { + matcher: ['/', '/mydashboard/:path*', '/dashboard/:path*', '/mypage/:path*'], +}