- 테스트베드 프록시 설정 키 및 기능 추가(DjbApiSpecController)
eapim-admin CI / build (push) Has been cancelled

- 인증 스킴 라벨 판별 로직(schemeAuthLabel) 및 프록시 사용 여부 표시 로직 추가
- JSP/JS: 프록시 여부 관련 UI 및 데이터 연계 처리
This commit is contained in:
Rinjae
2026-07-23 20:26:11 +09:00
parent 406dd34e28
commit 26679cf649
3 changed files with 64 additions and 8 deletions
+38 -8
View File
@@ -25,6 +25,10 @@
components: [], // 재사용 스키마(POC: 빈 상태)
};
// GW authtype(oauth/api_key 등, 서버 DETAIL_SPEC 응답). 인증 badge 라벨 판별용.
// (enricher 는 oauth·api_key 를 모두 apiKey-in-header 로 모델링하므로 scheme.type 만으로 구분 불가)
var djbAuthType = '';
// ============================================================
// 2. 유틸
// ============================================================
@@ -755,22 +759,44 @@
// ============================================================
// 9. 인증 / 보안 (기본정보 Step 에 병합된 섹션)
// ============================================================
// 테스트베드 프록시 사용 여부(포탈 djb.gateway.use-proxy / token-use-proxy). DJB_CTX 미지정 시 기본 true.
function useProxyOn() { return !(window.DJB_CTX && window.DJB_CTX.useProxy === false); }
function tokenProxyOn() { return !(window.DJB_CTX && window.DJB_CTX.tokenUseProxy === false); }
// 인증 스킴 → 실제 인증방식 라벨/색상. GW enricher 는 oauth·api_key 를 모두 apiKey-in-header 로 모델링하므로
// scheme.type("apiKey")만으로는 구분 불가 → authtype(djbAuthType) 및 scheme key(djbOAuth/djbApiKey)로 판별.
function schemeAuthLabel(s) {
var at = (djbAuthType || '').trim().toLowerCase();
if (at === 'oauth' || at === 'oauth2' || at === 'ca' || s.key === 'djbOAuth') {
return { label: 'OAUTH', cls: 'bg-purple-100 text-purple-700' };
}
if (at === 'api_key' || at === 'apikey' || s.key === 'djbApiKey') {
return { label: 'API KEY', cls: 'bg-emerald-100 text-emerald-700' };
}
return { label: (s.type || '').toUpperCase(), cls: 'bg-slate-100 text-slate-700' };
}
function renderAuthSection() {
var schemes = state.data.securitySchemes || [];
var proxyOn = useProxyOn();
var notice =
'<div class="mb-3 text-xs bg-slate-50 border border-slate-200 rounded p-2 leading-relaxed text-slate-600">'
+ '<div>Swagger 테스트 호출: <b>' + (proxyOn ? '포탈 프록시 경유' : '직접 호출') + '</b>'
+ (proxyOn ? ' — <code class="font-mono">/api/call-api</code> 가 인증 토큰·헤더를 대신 주입합니다.'
: ' — 브라우저가 대상 주소로 직접 호출(대상 CORS 허용 필요).') + '</div>'
+ '<div>토큰 발급: <b>' + (tokenProxyOn() ? '포탈 프록시 경유' : '직접 호출') + '</b></div>'
+ '<div class="text-slate-400 mt-1">프록시 여부는 포탈 설정 <code class="font-mono">djb.gateway.use-proxy</code> / <code class="font-mono">djb.gateway.token-use-proxy</code> 로 제어됩니다.</div>'
+ '</div>';
return card(
sectionTitle('인증 / 보안', '게이트웨이(GW)에 설정된 인증만 표시됩니다. (읽기 전용)') +
notice +
(schemes.length
? schemes.map((s, i) => renderSecuritySchemeCard(s, i)).join('')
: '<div class="text-sm text-slate-500 py-2">인증 없음</div>')
);
}
function renderSecuritySchemeCard(s, idx) {
const typeBadge = {
apiKey: 'bg-emerald-100 text-emerald-700',
http: 'bg-blue-100 text-blue-700',
oauth2: 'bg-purple-100 text-purple-700',
openIdConnect: 'bg-slate-100 text-slate-700'
}[s.type] || 'bg-slate-100 text-slate-700';
const auth = schemeAuthLabel(s);
let body = '';
if (s.type === 'apiKey') {
@@ -797,7 +823,7 @@
<div class="border border-slate-200 rounded-lg p-3 mb-3 locked-card">
<div class="flex items-center gap-2 mb-3">
<code class="text-sm font-semibold text-slate-800">${escapeHtml(s.key)}</code>
<span class="px-2 py-0.5 text-[10px] uppercase rounded ${typeBadge}">${escapeHtml(s.type)}</span>
<span class="px-2 py-0.5 text-[10px] uppercase rounded ${auth.cls}">${escapeHtml(auth.label)}</span>
<span class="text-xs text-slate-400 ml-1">🔒 GW</span>
</div>
${body}
@@ -1030,7 +1056,9 @@
).join('') +
(rt === 'sample'
? `<div class="mt-2 text-xs text-slate-500">응답 샘플을 바로 리턴합니다.</div>`
: `<div class="mt-2 text-xs text-slate-500">실제 호출 주소: <code id="resolved-call-url" class="font-mono text-slate-700 break-all">${escapeHtml(resolvedCallUrl())}</code></div>`) +
: `<div class="mt-2 text-xs text-slate-500">실제 호출 주소: <code id="resolved-call-url" class="font-mono text-slate-700 break-all">${escapeHtml(resolvedCallUrl())}</code></div>`
+ `<div class="mt-1 text-xs text-slate-500">호출 방식: <b>${useProxyOn() ? '포탈 프록시 경유' : '직접 호출'}</b>`
+ (useProxyOn() ? ' (<code class="font-mono">/api/call-api</code> 경유, 인증 헤더 자동 주입)' : ' (브라우저 → 대상 직접 호출, 대상 CORS 허용 필요)') + `</div>`) +
(rt === 'gw' ? `<div class="mt-1 text-xs text-slate-400">GW 주소는 포탈 설정(PTL_PROPERTY, 그룹 Portal)의 <code class="font-mono">djb.gateway.base-url</code> 값을 사용합니다.</div>` : '') +
'</div>') +
(rt === 'mock' ? fieldRow('Mock Server URL', input(p.mockUrl || '', 'data-portal="mockUrl"', { placeholder: 'https://mock.example.com/api/v1/foo' }), { hint: 'Mock 응답을 제공할 전체 호출 URL(경로 포함). 응답 유형이 Mock 일 때 이 주소로 그대로 호출하며, 어댑터/오퍼레이션 경로를 뒤에 덧붙이지 않습니다.' }) : '')
@@ -1950,6 +1978,7 @@
if (res && res.testbedSpec) {
try { state.data = specToData(JSON.parse(res.testbedSpec)); } catch (e) { console.error('specToData', e); }
}
djbAuthType = (res && res.authType) || ''; // 인증 badge 라벨 판별용(oauth/api_key)
// 자동생성 규칙(title/tag/summary=API명, 예제, 서버prepend, opId)은 백엔드에서 적용됨 → 그대로 로드
state.step = 1; state.responseStatusTab = state.data.responses && state.data.responses['200'] ? '200' : (state.data.responses ? Object.keys(state.data.responses)[0] : '200');
var _nm = decodeEntities(ctx.apiName || '') || state.data.info.title.value || '';
@@ -2029,6 +2058,7 @@
try { state.data = specToData(JSON.parse(res.testbedSpec)); }
catch (e) { toast('자동 생성 실패: 스펙 파싱 오류', 'error'); return; }
}
djbAuthType = (res && res.authType) || ''; // 인증 badge 라벨 판별용(oauth/api_key)
// 구조(title/tag/summary/opId/스키마/보안/헤더)는 백엔드(generateSpec)가 적용한 기초 스펙 그대로 로드.
// 추가자료(예제·설명자료)는 프론트에서 스키마 기준 생성 → 재생성 버튼과 동일 결과.
frontAutoGenerate();