SSO 중복 인증 사용 오류 개선
Deploy EG-BIM QA Gateway / deploy (push) Successful in 33s

This commit is contained in:
root committed 2026-09-22 15:45:55 +09:00
1 parent c6b430a197
commit ee5205e133
4 files changed
+33 -13

No files matched your search

+13 -7
View File
@@ -96,6 +96,8 @@ function redirect(url, headers = {}) {
else responseHeaders.set(name, value);
});
responseHeaders.set('location', url);
responseHeaders.set('cache-control', 'no-store, no-cache, must-revalidate');
responseHeaders.set('pragma', 'no-cache');
return new Response(null, { status: 302, headers: responseHeaders });
}
@@ -250,32 +252,36 @@ async function startLogin(request, env) {
return redirect(authorize.toString(), { 'set-cookie': cookie(env.OAUTH_COOKIE_NAME, signedState, 600) });
}
function oauthError(env, error, detail, status) {
return json({ error, detail: detail || '' }, status, { 'set-cookie': cookie(env.OAUTH_COOKIE_NAME, '', 0, { delete: true }) });
}
async function finishLogin(request, env) {
const missing = requiredAuthConfig(env);
if (missing.length) return json({ error: 'auth_not_configured', missing }, 503);
const url = new URL(request.url);
const signedState = getCookie(request, env.OAUTH_COOKIE_NAME);
const statePayload = await verifyValue(signedState, env.SESSION_SECRET);
if (!statePayload) return json({ error: 'invalid_oauth_state' }, 400);
if (!statePayload) return oauthError(env, 'invalid_oauth_state', '', 400);
let state;
try { state = JSON.parse(decoder.decode(fromBase64url(statePayload))); } catch (error) { return json({ error: 'invalid_oauth_state' }, 400); }
if (url.searchParams.get('state') !== state.state || Date.now() - state.createdAt > 10 * 60 * 1000) return json({ error: 'invalid_oauth_state' }, 400);
try { state = JSON.parse(decoder.decode(fromBase64url(statePayload))); } catch (error) { return oauthError(env, 'invalid_oauth_state', '', 400); }
if (url.searchParams.get('state') !== state.state || Date.now() - state.createdAt > 10 * 60 * 1000) return oauthError(env, 'invalid_oauth_state', '', 400);
const code = url.searchParams.get('code');
if (!code) return json({ error: 'oauth_code_missing', detail: url.searchParams.get('error_description') || url.searchParams.get('error') || '' }, 400);
if (!code) return oauthError(env, 'oauth_code_missing', url.searchParams.get('error_description') || url.searchParams.get('error') || '', 400);
const tokenParams = new URLSearchParams({ grant_type: 'authorization_code', client_id: env.AUTH_CLIENT_ID, redirect_uri: env.AUTH_REDIRECT_URI, code, code_verifier: state.verifier });
const tokenResponse = await fetch(env.AUTH_TOKEN_URL, { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded', accept: 'application/json' }, body: tokenParams });
const tokens = await tokenResponse.json().catch(() => ({}));
if (!tokenResponse.ok) return json({ error: 'oauth_token_exchange_failed', detail: tokens.error_description || tokens.error || '' }, 502);
if (!tokenResponse.ok) return oauthError(env, 'oauth_token_exchange_failed', tokens.error_description || tokens.error || '', 502);
let claims = parseJwt(tokens.id_token || tokens.access_token);
if (state.nonce && claims.nonce && state.nonce !== claims.nonce) return json({ error: 'invalid_oauth_nonce' }, 400);
if (state.nonce && claims.nonce && state.nonce !== claims.nonce) return oauthError(env, 'invalid_oauth_nonce', '', 400);
if (env.AUTH_USERINFO_URL && tokens.access_token) {
const userResponse = await fetch(env.AUTH_USERINFO_URL, { headers: { authorization: `Bearer ${tokens.access_token}`, accept: 'application/json' } });
const userInfo = await userResponse.json().catch(() => ({}));
if (userResponse.ok) claims = { ...claims, ...userInfo };
}
const user = normalizeClaims(claims);
if (!user.ssoSubject) return json({ error: 'sso_subject_missing' }, 502);
if (!user.ssoSubject) return oauthError(env, 'sso_subject_missing', '', 502);
const sessionPayload = base64url(JSON.stringify({ user, expiresAt: Date.now() + Number(env.SESSION_TTL_SECONDS || 3600) * 1000 }));
const session = await signValue(sessionPayload, env.SESSION_SECRET);
return redirect(new URL(state.returnUrl || '/', url.origin).toString(), { 'set-cookie': [cookie(env.SESSION_COOKIE_NAME, session, Number(env.SESSION_TTL_SECONDS || 3600)), cookie(env.OAUTH_COOKIE_NAME, '', 0, { delete: true })] });