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;