Files
sam-kd/opendart/api/proxy_helper.php
hskwon aca1767eb9 초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경
- DB 연결 하드코딩 → .env 기반으로 변경
- MySQL strict mode DATE 오류 수정
2025-12-10 20:14:31 +09:00

185 lines
5.5 KiB
PHP

<?php
/**
* Open DART API Proxy Helper
*
* 멀티테넌시 환경을 위한 프록시 함수
* 클라이언트의 IP 대신 서버의 IP로 Open DART API를 호출하여
* IP 화이트리스트 제한을 우회합니다.
*
* 동작 방식:
* 1. 클라이언트 요청 → 회사 서버 (이 파일)
* 2. 회사 서버 → Open DART API (등록된 IP로 호출)
* 3. Open DART 응답 → 회사 서버
* 4. 회사 서버 → 클라이언트
*/
/**
* Open DART API를 프록시를 통해 호출
*
* @param string $endpoint Open DART API 엔드포인트 (예: 'company.json', 'corpCode.xml')
* @param array $params API 파라미터 배열
* @param string $apiKey Open DART API 키 (null이면 기본 파일에서 로드)
* @param array $options 추가 옵션 (timeout, method 등)
* @return array ['success' => bool, 'data' => mixed, 'error' => string]
*/
function callOpenDartAPI($endpoint, $params = [], $apiKey = null, $options = []) {
// API Key 로드
if ($apiKey === null) {
$apiKeyPath = $_SERVER['DOCUMENT_ROOT'] . '/apikey/opendart.txt';
if (!file_exists($apiKeyPath)) {
return [
'success' => false,
'data' => null,
'error' => 'API Key file not found.'
];
}
$apiKey = trim(file_get_contents($apiKeyPath));
}
if (empty($apiKey)) {
return [
'success' => false,
'data' => null,
'error' => 'API Key is empty.'
];
}
// 기본 옵션
$defaultOptions = [
'timeout' => 30,
'method' => 'GET',
'return_type' => 'json', // 'json' or 'xml' or 'raw'
'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
];
$options = array_merge($defaultOptions, $options);
// 파라미터에 API 키 추가
$params['crtfc_key'] = $apiKey;
// URL 구성
$baseUrl = 'https://opendart.fss.or.kr/api/';
$url = $baseUrl . $endpoint;
if ($options['method'] === 'GET' && !empty($params)) {
$url .= '?' . http_build_query($params);
}
// cURL 설정
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, $options['timeout']);
curl_setopt($ch, CURLOPT_USERAGENT, $options['user_agent']);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
// POST 요청 처리 (필요한 경우)
if ($options['method'] === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
}
// 실행
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
$effectiveUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
curl_close($ch);
// 에러 처리
if ($httpCode !== 200 || !$response) {
$errorMsg = 'Failed to fetch data from Open DART.';
if ($curlError) {
$errorMsg .= ' cURL Error: ' . $curlError;
}
if ($httpCode) {
$errorMsg .= ' HTTP Code: ' . $httpCode;
}
// IP 접근 오류 체크
if ($response && (strpos($response, '접근할 수 없는 IP') !== false || strpos($response, 'Inaccessible IP') !== false)) {
$xml = @simplexml_load_string($response);
if ($xml && isset($xml->message)) {
$errorMsg = 'IP 접근 오류: ' . (string)$xml->message;
}
}
return [
'success' => false,
'data' => null,
'error' => $errorMsg,
'http_code' => $httpCode,
'raw_response' => $response
];
}
// 응답 처리
$data = $response;
if ($options['return_type'] === 'json') {
$decoded = json_decode($response, true);
if ($decoded !== null) {
$data = $decoded;
}
} elseif ($options['return_type'] === 'xml') {
$xml = @simplexml_load_string($response);
if ($xml !== false) {
$data = $xml;
}
}
return [
'success' => true,
'data' => $data,
'error' => null,
'http_code' => $httpCode,
'raw_response' => $response
];
}
/**
* 서버의 공인 IP 확인
*
* @return string 공인 IP 주소
*/
function getServerPublicIP() {
// Try multiple methods to get public IP
$ipServices = [
'https://api.ipify.org',
'https://checkip.amazonaws.com',
'https://icanhazip.com',
'https://ifconfig.me/ip'
];
foreach ($ipServices as $service) {
$ch = curl_init($service);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$ip = trim(curl_exec($ch));
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200 && filter_var($ip, FILTER_VALIDATE_IP)) {
return $ip;
}
}
// Fallback: try to get from $_SERVER
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$ip = trim($ips[0]);
if (filter_var($ip, FILTER_VALIDATE_IP)) {
return $ip;
}
}
if (!empty($_SERVER['REMOTE_ADDR'])) {
return $_SERVER['REMOTE_ADDR'];
}
return 'Unknown';
}
?>