diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 4fff682..1483422 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -66,14 +66,20 @@ export default function LoginPage() { const token = data.token || data.accessToken || data.access_token; if (token) { localStorage.setItem('token', token); + // 쿠키에도 토큰 저장 (middleware에서 사용) + document.cookie = `token=${token}; path=/; max-age=${30 * 24 * 60 * 60}; SameSite=Lax`; console.log("토큰 저장 완료"); } else { console.warn("토큰이 응답에 없습니다. 응답 데이터:", data); // 토큰이 없어도 로그인은 성공했으므로 진행 } + // 리다이렉트 경로 확인 + const searchParams = new URLSearchParams(window.location.search); + const redirectPath = searchParams.get('redirect') || '/'; + // 메인 페이지로 이동 - router.push('/'); + router.push(redirectPath); } catch (error) { const errorMessage = error instanceof Error ? error.message : "네트워크 오류가 발생했습니다."; console.error("로그인 오류:", errorMessage); diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..6c7c057 --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,57 @@ +import { NextResponse } from 'next/server'; +import type { NextRequest } from 'next/server'; + +export function middleware(request: NextRequest) { + const { pathname } = request.nextUrl; + + // 공개 경로 (인증 불필요) + const publicPaths = [ + '/login', + '/register', + '/find-id', + '/reset-password', + ]; + + // 정적 파일 및 API 경로는 제외 + if ( + pathname.startsWith('/_next') || + pathname.startsWith('/api') || + pathname.startsWith('/fonts') || + pathname.startsWith('/imgs') || + pathname.match(/\.(ico|png|jpg|jpeg|svg|woff|woff2)$/) + ) { + return NextResponse.next(); + } + + // 공개 경로는 통과 + if (publicPaths.some(path => pathname.startsWith(path))) { + return NextResponse.next(); + } + + // 토큰 확인 (쿠키에서) + const token = request.cookies.get('token')?.value; + + // 토큰이 없으면 로그인 페이지로 리다이렉트 + if (!token) { + const loginUrl = new URL('/login', request.url); + // 원래 요청한 경로를 쿼리 파라미터로 저장 (로그인 후 돌아갈 수 있도록) + loginUrl.searchParams.set('redirect', pathname); + return NextResponse.redirect(loginUrl); + } + + return NextResponse.next(); +} + +export const config = { + matcher: [ + /* + * Match all request paths except for the ones starting with: + * - api (API routes) + * - _next/static (static files) + * - _next/image (image optimization files) + * - favicon.ico (favicon file) + */ + '/((?!api|_next/static|_next/image|favicon.ico).*)', + ], +}; +