import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { refreshAccessToken } from '@/lib/api/refresh-token'; /** * ๐Ÿ”ต Next.js ๋‚ด๋ถ€ API - ์ธ์ฆ ์ƒํƒœ ํ™•์ธ (PHP ๋ฐฑ์—”๋“œ X) * * โšก ์„ค๊ณ„ ๋ชฉ์ : * - ์„ฑ๋Šฅ ์ตœ์ ํ™”: ๋งค๋ฒˆ PHP ๋ฐฑ์—”๋“œ ํ˜ธ์ถœ ๋Œ€์‹  ๋กœ์ปฌ ์ฟ ํ‚ค๋งŒ ํ™•์ธ * - ๋ฐฑ์—”๋“œ ๋ถ€ํ•˜ ๊ฐ์†Œ: ๊ฐ„๋‹จํ•œ ์ธ์ฆ ํ™•์ธ์€ Next.js์—์„œ ์ฒ˜๋ฆฌ * - ์‚ฌ์šฉ์ž ๊ฒฝํ—˜: ์ฆ‰์‹œ ์‘๋‹ต์œผ๋กœ ๋น ๋ฅธ ํŽ˜์ด์ง€ ์ „ํ™˜ * * ๐Ÿ“ ์‚ฌ์šฉ ์œ„์น˜: * - LoginPage.tsx: ์ด๋ฏธ ๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹œ๋ณด๋“œ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ * - SignupPage.tsx: ์ด๋ฏธ ๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹œ๋ณด๋“œ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ * - ๋’ค๋กœ๊ฐ€๊ธฐ ์‹œ ์บ์‹œ ๋ฌธ์ œ ๋ฐฉ์ง€ * * ๐Ÿ”„ ๋™์ž‘ ๋ฐฉ์‹: * 1. HttpOnly ์ฟ ํ‚ค์—์„œ access_token, refresh_token ํ™•์ธ * 2. access_token ์žˆ์Œ โ†’ { authenticated: true } ์ฆ‰์‹œ ์‘๋‹ต * 3. refresh_token๋งŒ ์žˆ์Œ โ†’ PHP /api/v1/refresh ํ˜ธ์ถœํ•˜์—ฌ ํ† ํฐ ๊ฐฑ์‹  * 4. ๋‘˜ ๋‹ค ์—†์Œ โ†’ { authenticated: false } ์‘๋‹ต * * โš ๏ธ ์ฃผ์˜: * - ์ด API๋Š” PHP ๋ฐฑ์—”๋“œ์— ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค * - Next.js ํ”„๋ก ํŠธ์—”๋“œ ์ž์ฒด ์œ ํ‹ธ๋ฆฌํ‹ฐ API์ž…๋‹ˆ๋‹ค * - ์‹ค์ œ ์ธ์ฆ ๋กœ์ง์€ ์—ฌ์ „ํžˆ PHP ๋ฐฑ์—”๋“œ๊ฐ€ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค */ export async function GET(request: NextRequest) { try { // Get tokens from HttpOnly cookies const accessToken = request.cookies.get('access_token')?.value; const refreshToken = request.cookies.get('refresh_token')?.value; // No tokens at all - not authenticated if (!accessToken && !refreshToken) { return NextResponse.json( { error: 'Not authenticated' }, { status: 401 } ); } // Has access token - authenticated if (accessToken) { return NextResponse.json( { authenticated: true }, { status: 200 } ); } // Only has refresh token - try to refresh if (refreshToken && !accessToken) { console.log('๐Ÿ”„ [auth/check] Access token missing, attempting refresh...'); // ๊ณต์œ  ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” refreshAccessToken ํ•จ์ˆ˜ ์‚ฌ์šฉ const refreshResult = await refreshAccessToken(refreshToken, 'auth/check'); if (refreshResult.success && refreshResult.accessToken) { console.log('โœ… [auth/check] Token refreshed successfully'); // Set new tokens with Safari-compatible configuration const isProduction = process.env.NODE_ENV === 'production'; const accessTokenCookie = [ `access_token=${refreshResult.accessToken}`, 'HttpOnly', ...(isProduction ? ['Secure'] : []), 'SameSite=Lax', 'Path=/', `Max-Age=${refreshResult.expiresIn || 7200}`, ].join('; '); const refreshTokenCookie = [ `refresh_token=${refreshResult.refreshToken}`, 'HttpOnly', ...(isProduction ? ['Secure'] : []), 'SameSite=Lax', 'Path=/', 'Max-Age=604800', ].join('; '); const response = NextResponse.json( { authenticated: true, refreshed: true }, { status: 200 } ); response.headers.append('Set-Cookie', accessTokenCookie); response.headers.append('Set-Cookie', refreshTokenCookie); return response; } // Refresh failed - not authenticated console.log('โš ๏ธ [auth/check] Refresh failed, returning 401'); return NextResponse.json( { error: 'Token refresh failed' }, { status: 401 } ); } // Fallback - not authenticated return NextResponse.json( { error: 'Not authenticated' }, { status: 401 } ); } catch (error) { console.error('Auth check error:', error); return NextResponse.json( { error: 'Internal server error', authenticated: false }, { status: 500 } ); } }