@@ -4,27 +4,31 @@ import type { NextRequest } from 'next/server';
44export async function middleware ( request : NextRequest ) {
55 const { pathname } = request . nextUrl ;
66
7- // /admin/dashboard 경로에 대한 인증 확인
8- if ( pathname . startsWith ( '/admin/dashboard' ) && ! pathname . startsWith ( '/admin/dashboard/auth' ) ) {
7+ // basePath를 고려한 경로 확인
8+ // basePath가 /admin/dashboard이므로, 앱 내부에서는 / 부터 시작
9+ // 예: 브라우저 URL /admin/dashboard/users -> 앱 내부 pathname /users
10+
11+ // 인증이 필요한 경로 확인 (auth 경로 제외)
12+ if ( ! pathname . startsWith ( '/auth' ) ) {
913 console . log ( 'Middleware: Checking auth for:' , pathname ) ;
10-
14+
1115 // 모든 쿠키 로그
1216 const allCookies = request . cookies . getAll ( ) ;
1317 console . log ( 'Middleware: All cookies:' , allCookies ) ;
14-
18+
1519 // 여러 방법으로 토큰 읽기 시도
1620 const token = request . cookies . get ( 'auth_token' ) ?. value ;
1721 const cookieHeader = request . headers . get ( 'cookie' ) ;
1822 console . log ( 'Middleware: Raw cookie header:' , cookieHeader ) ;
1923 console . log ( 'Middleware: auth_token value:' , token ? `Found token (${ token . length } chars)` : 'No token' ) ;
20-
24+
2125 if ( ! token ) {
2226 console . log ( 'Middleware: No token found, redirecting to login' ) ;
23- // 토큰이 없으면 로그인 페이지로 리다이렉트
24- const loginUrl = new URL ( '/admin/dashboard/ auth/login' , request . url ) ;
27+ // basePath를 고려하여 상대 경로로 리다이렉트
28+ const loginUrl = new URL ( '/auth/login' , request . url ) ;
2529 return NextResponse . redirect ( loginUrl ) ;
2630 }
27-
31+
2832 // 서버 사이드에서 토큰 검증 및 ADMIN 역할 확인
2933 try {
3034 const response = await fetch ( 'https://prod.windeath44.wiki/api/users/profile' , {
@@ -36,59 +40,53 @@ export async function middleware(request: NextRequest) {
3640 // Edge Runtime에서는 cache 옵션 사용
3741 cache : 'no-store' ,
3842 } ) ;
39-
43+
4044 if ( ! response . ok ) {
4145 console . log ( 'Token validation failed in middleware:' , response . status ) ;
4246 // 토큰이 유효하지 않으면 로그인 페이지로 리다이렉트하고 토큰 삭제
43- const loginUrl = new URL ( '/admin/dashboard/ auth/login' , request . url ) ;
47+ const loginUrl = new URL ( '/auth/login' , request . url ) ;
4448 const redirectResponse = NextResponse . redirect ( loginUrl ) ;
4549 redirectResponse . cookies . set ( 'auth_token' , '' , { expires : new Date ( 0 ) } ) ;
4650 return redirectResponse ;
4751 }
48-
52+
4953 const userProfile = await response . json ( ) ;
5054 console . log ( 'Middleware: API response:' , JSON . stringify ( userProfile , null , 2 ) ) ;
51-
55+
5256 // role은 data 객체 안에 중첩되어 있음
5357 const userRole = userProfile . data ?. role ;
5458 console . log ( 'Middleware: User role found:' , userRole ) ;
55-
59+
5660 if ( userRole !== 'ADMIN' ) {
5761 console . log ( 'User does not have ADMIN role in middleware:' , userRole ) ;
5862 // ADMIN 역할이 아니면 로그인 페이지로 리다이렉트하고 토큰 삭제
59- const loginUrl = new URL ( '/admin/dashboard/ auth/login' , request . url ) ;
63+ const loginUrl = new URL ( '/auth/login' , request . url ) ;
6064 loginUrl . searchParams . set ( 'access_denied' , 'true' ) ;
6165 const redirectResponse = NextResponse . redirect ( loginUrl ) ;
6266 redirectResponse . cookies . set ( 'auth_token' , '' , { expires : new Date ( 0 ) } ) ;
6367 return redirectResponse ;
6468 }
65-
69+
6670 // 유효한 ADMIN 토큰이면 진행
6771 console . log ( 'Valid ADMIN token verified in middleware' ) ;
6872 return NextResponse . next ( ) ;
69-
73+
7074 } catch ( error ) {
7175 console . error ( 'Token validation error in middleware:' , error ) ;
7276 // 에러 발생 시 로그인 페이지로 리다이렉트하고 토큰 삭제
73- const loginUrl = new URL ( '/admin/dashboard/ auth/login' , request . url ) ;
77+ const loginUrl = new URL ( '/auth/login' , request . url ) ;
7478 const redirectResponse = NextResponse . redirect ( loginUrl ) ;
7579 redirectResponse . cookies . set ( 'auth_token' , '' , { expires : new Date ( 0 ) } ) ;
7680 return redirectResponse ;
7781 }
7882 }
7983
80- // 루트 경로를 /admin/dashboard로 리다이렉트
81- if ( pathname === '/' ) {
82- const dashboardUrl = new URL ( '/admin/dashboard' , request . url ) ;
83- return NextResponse . redirect ( dashboardUrl ) ;
84- }
85-
8684 return NextResponse . next ( ) ;
8785}
8886
8987export const config = {
9088 matcher : [
91- '/' ,
92- '/admin/dashboard/:path* ' ,
89+ // basePath가 적용되므로 앱 내부 경로로 매칭
90+ '/((?!auth|_next/static|_next/image|favicon.ico).*) ' ,
9391 ] ,
9492} ;
0 commit comments