1
0
forked from baron/baron-sso

디버깅 로그 추가

This commit is contained in:
Lectom C Han
2026-02-19 13:25:45 +09:00
parent 6fd0e5c800
commit f617467082
5 changed files with 334 additions and 23 deletions

View File

@@ -11,6 +11,7 @@ import '../../../core/services/auth_proxy_service.dart';
import '../../../core/services/auth_token_store.dart';
import '../../../core/services/oidc_redirect_guard.dart';
import '../../../core/notifiers/auth_notifier.dart';
import '../domain/password_login_flow_policy.dart';
import '../../profile/domain/notifiers/profile_notifier.dart';
import '../../../core/services/web_window.dart';
@@ -167,11 +168,15 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
Future<void> _onCookieLoginSuccess(String provider) async {
debugPrint("[Auth] Cookie-based login success. Provider: $provider");
AuthNotifier.instance.notify();
if (_loginChallenge != null && _loginChallenge!.isNotEmpty) {
if (_hasLoginChallenge) {
final accepted = await _acceptOidcLoginAndRedirect();
if (accepted) {
return;
}
if (mounted) {
_showError(tr('msg.userfront.login.oidc_failed'));
}
return;
}
final token = AuthTokenStore.getToken();
@@ -238,6 +243,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
bool _redirectToOidcTarget(String redirectTo, {required String source}) {
final checked = validateOidcRedirectTarget(redirectTo);
_logOidcRedirectDiagnostics(source: source, checked: checked);
debugPrint(
"[Auth] OIDC redirect check ($source): valid=${checked.isValid}, reason=${checked.reason}, len=${checked.length}, host=${checked.host}, path=${checked.path}, has_login_verifier=${checked.hasLoginVerifier}",
);
@@ -249,8 +255,42 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
return false;
}
webWindow.redirectTo(checked.uri.toString());
return true;
try {
debugPrint(
"[Auth] OIDC redirect execute ($source): host=${checked.host}, path=${checked.path}, redirect_uri_host=${checked.redirectUriHost}, redirect_uri_port=${checked.redirectUriPort}, state_len=${checked.stateLength}, login_verifier_len=${checked.loginVerifierLength}",
);
webWindow.redirectTo(checked.uri.toString());
return true;
} catch (e) {
debugPrint("[Auth] OIDC redirect failed ($source): $e");
if (mounted) {
_showError(tr('msg.userfront.login.oidc_failed'));
}
return false;
}
}
bool get _hasLoginChallenge =>
_loginChallenge != null && _loginChallenge!.isNotEmpty;
void _logOidcRedirectDiagnostics({
required String source,
required OidcRedirectCheckResult checked,
}) {
final current = Uri.base;
final currentQueryKeys = current.queryParameters.keys.toList()..sort();
final payload = <String, Object?>{
'source': source,
'current_path': current.path,
'current_query_param_count': current.queryParameters.length,
'current_query_keys': currentQueryKeys,
'has_login_challenge': _hasLoginChallenge,
'login_challenge_len': _loginChallenge?.length ?? 0,
...checked.toDiagnostics(),
};
debugPrint("[Auth] OIDC redirect diagnostics: ${jsonEncode(payload)}");
}
void _resetLinkLoginState() {
@@ -829,17 +869,44 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
password,
loginChallenge: _loginChallenge,
);
final jwt = res['sessionJwt'] ?? res['sessionToken'] ?? res['token'];
final jwtRaw = res['sessionJwt'] ?? res['sessionToken'] ?? res['token'];
final jwt = jwtRaw?.toString();
final provider = res['provider'] as String?;
final redirectTo = res['redirectTo'] as String?;
final hasJwt = jwt != null && jwt.isNotEmpty;
final nextAction = decidePasswordLoginNextAction(
hasLoginChallenge: _hasLoginChallenge,
redirectTo: redirectTo,
jwt: jwt,
);
if (redirectTo != null && redirectTo.isNotEmpty) {
_redirectToOidcTarget(redirectTo, source: 'password_login');
return;
}
debugPrint(
"[Auth] Password login outcome: has_login_challenge=$_hasLoginChallenge, next_action=$nextAction, has_jwt=$hasJwt",
);
if (jwt != null) {
_onLoginSuccess(jwt, provider: provider);
switch (nextAction) {
case PasswordLoginNextAction.redirectToOidc:
_redirectToOidcTarget(redirectTo!, source: 'password_login');
return;
case PasswordLoginNextAction.acceptOidc:
final accepted = await _acceptOidcLoginAndRedirect(
token: hasJwt ? jwt : null,
);
if (accepted) {
return;
}
if (mounted) {
_showError(tr('msg.userfront.login.oidc_failed'));
}
return;
case PasswordLoginNextAction.localLogin:
_onLoginSuccess(jwt!, provider: provider);
return;
case PasswordLoginNextAction.invalid:
if (mounted) {
_showError(tr('msg.userfront.login.password.failed'));
}
return;
}
} catch (e) {
if (e.toString().contains("User not registered")) {
@@ -1080,20 +1147,16 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
debugPrint("[Auth] Failed to pre-fetch profile: $e");
}
if (_loginChallenge != null && _loginChallenge!.isNotEmpty) {
if (_hasLoginChallenge) {
try {
final res = await AuthProxyService.acceptOidcLogin(
_loginChallenge!,
token: token,
);
final redirectTo = res['redirectTo'] as String?;
if (redirectTo != null && redirectTo.isNotEmpty) {
_redirectToOidcTarget(
redirectTo,
source: 'on_login_success_accept_oidc',
);
final accepted = await _acceptOidcLoginAndRedirect(token: token);
if (accepted) {
return;
}
if (mounted) {
_showError(tr('msg.userfront.login.oidc_failed'));
}
return;
} catch (e) {
_showError(tr('msg.userfront.login.oidc_failed'));
return;