From 3627d70ad976bd98b9cd47c1e3f6e77facc1e148 Mon Sep 17 00:00:00 2001 From: kyy Date: Thu, 5 Feb 2026 10:04:42 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9E=AC=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=9C=20=EB=8F=99=EC=9D=98=20=ED=99=94=EB=A9=B4=20=EC=83=9D?= =?UTF-8?q?=EB=9E=B5=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/handler/auth_handler.go | 28 +++++++++++++++++++ .../auth/presentation/consent_screen.dart | 6 ++++ 2 files changed, 34 insertions(+) diff --git a/backend/internal/handler/auth_handler.go b/backend/internal/handler/auth_handler.go index 7b5d4595..1294bea5 100644 --- a/backend/internal/handler/auth_handler.go +++ b/backend/internal/handler/auth_handler.go @@ -3390,6 +3390,34 @@ func (h *AuthHandler) GetConsentRequest(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusInternalServerError, "Failed to get consent information") } + // [DEBUG] Hydra 응답 상세 로깅 + slog.Info("GetConsentRequest Debug", + "challenge", challenge, + "skip", consentRequest.Skip, + "subject", consentRequest.Subject, + "client_id", consentRequest.Client.ClientID, + "scopes", consentRequest.RequestedScope, + ) + + // Hydra가 이전에 동의한 이력이 있어 skip을 권장하는 경우, 즉시 승인 처리 + if consentRequest.Skip { + identity, err := h.KratosAdmin.GetIdentity(c.Context(), consentRequest.Subject) + if err != nil || identity == nil { + slog.Error("failed to load identity for skip consent", "error", err, "subject", consentRequest.Subject) + // 신원 정보를 가져오지 못하면 자동 승인을 진행할 수 없으므로 일반 흐름(UI 노출)으로 진행 + } else { + sessionClaims := buildOidcClaimsFromTraits(identity.Traits, consentRequest.RequestedScope) + acceptResp, err := h.Hydra.AcceptConsentRequest(c.Context(), challenge, consentRequest, sessionClaims) + if err != nil { + slog.Error("failed to auto-accept hydra consent request", "error", err) + // 자동 승인 실패 시 일반 흐름으로 진행 + } else { + slog.Info("Consent skipped and auto-accepted", "subject", consentRequest.Subject, "client", consentRequest.Client.ClientID) + return c.JSON(acceptResp) + } + } + } + // Hydra 응답을 기본으로 하되, 메타데이터에서 커스텀 스코프 설명을 추출하여 추가 response := fiber.Map{ "challenge": consentRequest.Challenge, diff --git a/userfront/lib/features/auth/presentation/consent_screen.dart b/userfront/lib/features/auth/presentation/consent_screen.dart index 93c7a761..7e5c7a2c 100644 --- a/userfront/lib/features/auth/presentation/consent_screen.dart +++ b/userfront/lib/features/auth/presentation/consent_screen.dart @@ -49,6 +49,12 @@ class _ConsentScreenState extends State { try { final info = await AuthProxyService.getConsentInfo(widget.consentChallenge); + // [Skip Logic] 백엔드에서 자동 승인되어 리다이렉트 URL이 온 경우 즉시 이동 + if (info['redirectTo'] != null) { + webWindow.redirectTo(info['redirectTo']); + return; + } + // 백엔드에서 전달받은 커스텀 스코프 정보(scope_details) 적용 if (info['scope_details'] != null) { final details = info['scope_details'] as Map;