Files
sam-react-prod/src/app/api/auth/logout/route.ts

102 lines
3.4 KiB
TypeScript
Raw Normal View History

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
/**
* 🔵 Next.js API - (PHP )
*
* :
* - 로그아웃: PHP +
* - 보안: HttpOnly
* - 정리: 클라이언트와
*
* 🔄 :
* 1. Next.js /api/auth/logout
* 2. Next.js: HttpOnly access_token
* 3. Next.js PHP /api/v1/logout ( )
* 4. Next.js: access_token, refresh_token
* 5. Next.js ( )
*
* 🔐 :
* - ( )
* - (Max-Age=0)
* - ( )
*
* :
* - API는 PHP /api/v1/logout의
* - ( )
*/
export async function POST(request: NextRequest) {
try {
// Get access_token from HttpOnly cookie
const accessToken = request.cookies.get('access_token')?.value;
if (accessToken) {
// Call PHP backend logout API
try {
await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/v1/logout`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${accessToken}`,
'X-API-KEY': process.env.API_KEY || '',
},
});
console.log('✅ Backend logout API called successfully');
} catch (error) {
console.warn('⚠️ Backend logout API failed (continuing with cookie deletion):', error);
}
}
// Clear both HttpOnly cookies
// Safari compatibility: Must use same attributes as when setting cookies
const isProduction = process.env.NODE_ENV === 'production';
const clearAccessToken = [
'access_token=',
'HttpOnly',
...(isProduction ? ['Secure'] : []), // ✅ Match login/check cookie attributes
'SameSite=Lax', // ✅ Match login/check cookie attributes
'Path=/',
'Max-Age=0', // Delete immediately
].join('; ');
const clearRefreshToken = [
'refresh_token=',
'HttpOnly',
...(isProduction ? ['Secure'] : []), // ✅ Match login/check cookie attributes
'SameSite=Lax', // ✅ Match login/check cookie attributes
'Path=/',
'Max-Age=0', // Delete immediately
].join('; ');
// ✅ is_authenticated 쿠키도 삭제 (FCM 인증 상태 플래그)
const clearIsAuthenticated = [
'is_authenticated=',
...(isProduction ? ['Secure'] : []),
'SameSite=Lax',
'Path=/',
'Max-Age=0',
].join('; ');
console.log('✅ Logout complete - Access & Refresh tokens cleared');
const response = NextResponse.json(
{ message: 'Logged out successfully' },
{ status: 200 }
);
response.headers.append('Set-Cookie', clearAccessToken);
response.headers.append('Set-Cookie', clearRefreshToken);
response.headers.append('Set-Cookie', clearIsAuthenticated);
return response;
} catch (error) {
console.error('Logout proxy error:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}