- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경 - DB 연결 하드코딩 → .env 기반으로 변경 - MySQL strict mode DATE 오류 수정
185 lines
5.5 KiB
PHP
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';
|
|
}
|
|
?>
|
|
|