97 lines
2.5 KiB
TypeScript
97 lines
2.5 KiB
TypeScript
|
|
import { NextRequest, NextResponse } from 'next/server';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* PHP 백엔드 프록시 유틸리티
|
||
|
|
*
|
||
|
|
* 역할:
|
||
|
|
* - Next.js API Routes → PHP Backend 단순 프록시
|
||
|
|
* - HttpOnly 쿠키의 access_token을 Bearer token으로 전달
|
||
|
|
* - PHP 응답을 그대로 프론트엔드로 반환
|
||
|
|
*
|
||
|
|
* 보안:
|
||
|
|
* - tenant.id 검증은 PHP 백엔드에서 수행
|
||
|
|
* - Next.js는 단순히 요청/응답 전달만
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* PHP 백엔드로 프록시 요청 전송
|
||
|
|
*
|
||
|
|
* @param request NextRequest 객체
|
||
|
|
* @param phpEndpoint PHP 백엔드 엔드포인트 (예: '/api/v1/tenants/282/item-master-config')
|
||
|
|
* @param options fetch options (method, body 등)
|
||
|
|
* @returns NextResponse
|
||
|
|
*/
|
||
|
|
export async function proxyToPhpBackend(
|
||
|
|
request: NextRequest,
|
||
|
|
phpEndpoint: string,
|
||
|
|
options?: RequestInit
|
||
|
|
): Promise<NextResponse> {
|
||
|
|
try {
|
||
|
|
// 1. 쿠키에서 access_token 추출
|
||
|
|
const accessToken = request.cookies.get('access_token')?.value;
|
||
|
|
|
||
|
|
if (!accessToken) {
|
||
|
|
return NextResponse.json(
|
||
|
|
{
|
||
|
|
success: false,
|
||
|
|
error: {
|
||
|
|
code: 'UNAUTHORIZED',
|
||
|
|
message: '인증이 필요합니다.',
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{ status: 401 }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. PHP 백엔드 URL 생성
|
||
|
|
const phpUrl = `${process.env.NEXT_PUBLIC_API_URL}${phpEndpoint}`;
|
||
|
|
|
||
|
|
// 3. PHP 백엔드 호출
|
||
|
|
const response = await fetch(phpUrl, {
|
||
|
|
...options,
|
||
|
|
headers: {
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
'Accept': 'application/json',
|
||
|
|
'Authorization': `Bearer ${accessToken}`,
|
||
|
|
'X-API-KEY': process.env.NEXT_PUBLIC_API_KEY || '',
|
||
|
|
...options?.headers,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
// 4. PHP 응답을 그대로 반환
|
||
|
|
const data = await response.json().catch(() => ({}));
|
||
|
|
|
||
|
|
return NextResponse.json(data, { status: response.status });
|
||
|
|
} catch (error) {
|
||
|
|
console.error('[PHP Proxy Error]', error);
|
||
|
|
|
||
|
|
return NextResponse.json(
|
||
|
|
{
|
||
|
|
success: false,
|
||
|
|
error: {
|
||
|
|
code: 'SERVER_ERROR',
|
||
|
|
message: '서버 오류가 발생했습니다.',
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{ status: 500 }
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Query Parameters를 URL에 추가하는 헬퍼
|
||
|
|
*
|
||
|
|
* @param baseUrl 기본 URL
|
||
|
|
* @param searchParams URLSearchParams
|
||
|
|
* @returns Query string이 추가된 URL
|
||
|
|
*/
|
||
|
|
export function appendQueryParams(baseUrl: string, searchParams: URLSearchParams): string {
|
||
|
|
const params = new URLSearchParams();
|
||
|
|
|
||
|
|
searchParams.forEach((value, key) => {
|
||
|
|
params.append(key, value);
|
||
|
|
});
|
||
|
|
|
||
|
|
const queryString = params.toString();
|
||
|
|
return queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
||
|
|
}
|