// /js/api-base.js // API 기본 설정 및 보안 유틸리티 - System 2 (신고 시스템) (function() { 'use strict'; // ==================== SSO 쿠키 유틸리티 ==================== function cookieGet(name) { var match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)')); return match ? decodeURIComponent(match[1]) : null; } function cookieRemove(name) { var cookie = name + '=; path=/; max-age=0'; if (window.location.hostname.includes('technicalkorea.net')) { cookie += '; domain=.technicalkorea.net'; } document.cookie = cookie; } /** * SSO 토큰 가져오기 (쿠키 우선, localStorage 폴백) */ window.getSSOToken = function() { return cookieGet('sso_token') || localStorage.getItem('sso_token'); }; window.getSSOUser = function() { var raw = cookieGet('sso_user') || localStorage.getItem('sso_user'); try { return raw ? JSON.parse(raw) : null; } catch(e) { return null; } }; /** * 중앙 로그인 URL 반환 (System 2 → tkfb 도메인의 로그인으로) */ window.getLoginUrl = function() { var hostname = window.location.hostname; if (hostname.includes('technicalkorea.net')) { return window.location.protocol + '//tkfb.technicalkorea.net/login?redirect=' + encodeURIComponent(window.location.href); } return window.location.protocol + '//' + hostname + ':30000/login?redirect=' + encodeURIComponent(window.location.href); }; window.clearSSOAuth = function() { cookieRemove('sso_token'); cookieRemove('sso_user'); cookieRemove('sso_refresh_token'); localStorage.removeItem('sso_token'); localStorage.removeItem('sso_user'); localStorage.removeItem('sso_refresh_token'); }; // ==================== 보안 유틸리티 (XSS 방지) ==================== window.escapeHtml = function(str) { if (str === null || str === undefined) return ''; if (typeof str !== 'string') str = String(str); var htmlEntities = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/', '`': '`', '=': '=' }; return str.replace(/[&<>"'`=\/]/g, function(char) { return htmlEntities[char]; }); }; window.escapeUrl = function(str) { if (str === null || str === undefined) return ''; return encodeURIComponent(String(str)); }; // ==================== API 설정 ==================== var API_PORT = 30105; var API_PATH = '/api'; function getApiBaseUrl() { var hostname = window.location.hostname; var protocol = window.location.protocol; // 프로덕션 환경 - 같은 도메인의 /api 경로 (system2-web nginx가 프록시) if (hostname.includes('technicalkorea.net')) { return protocol + '//' + hostname + API_PATH; } // 개발 환경 return protocol + '//' + hostname + ':' + API_PORT + API_PATH; } var apiUrl = getApiBaseUrl(); window.API_BASE_URL = apiUrl; window.API = apiUrl; // 인증 헤더 생성 - SSO 토큰 사용 (쿠키/localStorage) window.getAuthHeaders = function() { var token = window.getSSOToken(); return { 'Content-Type': 'application/json', 'Authorization': token ? 'Bearer ' + token : '' }; }; // API 호출 헬퍼 window.apiCall = async function(endpoint, method, data) { method = method || 'GET'; var url = window.API_BASE_URL + endpoint; var config = { method: method, headers: window.getAuthHeaders() }; if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'DELETE')) { config.body = JSON.stringify(data); } var response = await fetch(url, config); // 401 Unauthorized 처리 if (response.status === 401) { window.clearSSOAuth(); window.location.href = window.getLoginUrl(); throw new Error('인증이 만료되었습니다.'); } return response.json(); }; console.log('[System2] API 설정 완료:', window.API_BASE_URL); })();