forked from baron/baron-sso
리다이렉트 후속 로직 업데이트
This commit is contained in:
@@ -3,7 +3,6 @@ import 'package:http/http.dart' as http;
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:userfront/i18n.dart';
|
||||
import 'http_client.dart';
|
||||
import 'web_window.dart';
|
||||
import 'auth_token_store.dart';
|
||||
|
||||
class AuthProxyService {
|
||||
@@ -273,17 +272,11 @@ class AuthProxyService {
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
if (data['redirectTo'] != null && data['redirectTo'].isNotEmpty) {
|
||||
webWindow.redirectTo(data['redirectTo']);
|
||||
}
|
||||
return data;
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ??
|
||||
tr(
|
||||
'err.userfront.auth_proxy.login_failed',
|
||||
),
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.login_failed'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -304,10 +297,7 @@ class AuthProxyService {
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ??
|
||||
tr(
|
||||
'err.userfront.auth_proxy.consent_fetch',
|
||||
),
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.consent_fetch'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -333,10 +323,7 @@ class AuthProxyService {
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ??
|
||||
tr(
|
||||
'err.userfront.auth_proxy.consent_accept',
|
||||
),
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.consent_accept'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -358,10 +345,7 @@ class AuthProxyService {
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ??
|
||||
tr(
|
||||
'err.userfront.auth_proxy.consent_reject',
|
||||
),
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.consent_reject'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -388,10 +372,7 @@ class AuthProxyService {
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ??
|
||||
tr(
|
||||
'err.userfront.auth_proxy.oidc_accept',
|
||||
),
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.oidc_accept'),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
@@ -419,9 +400,7 @@ class AuthProxyService {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ??
|
||||
tr(
|
||||
'err.userfront.auth_proxy.password_reset_init',
|
||||
),
|
||||
tr('err.userfront.auth_proxy.password_reset_init'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -453,9 +432,7 @@ class AuthProxyService {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ??
|
||||
tr(
|
||||
'err.userfront.auth_proxy.password_reset_complete',
|
||||
),
|
||||
tr('err.userfront.auth_proxy.password_reset_complete'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -785,9 +762,7 @@ class AuthProxyService {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ??
|
||||
tr(
|
||||
'err.userfront.auth_proxy.linked_app_revoke',
|
||||
),
|
||||
tr('err.userfront.auth_proxy.linked_app_revoke'),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
|
||||
68
userfront/lib/core/services/oidc_redirect_guard.dart
Normal file
68
userfront/lib/core/services/oidc_redirect_guard.dart
Normal file
@@ -0,0 +1,68 @@
|
||||
class OidcRedirectCheckResult {
|
||||
final Uri? uri;
|
||||
final bool isValid;
|
||||
final String reason;
|
||||
final int length;
|
||||
final String host;
|
||||
final String path;
|
||||
final bool hasLoginVerifier;
|
||||
|
||||
const OidcRedirectCheckResult({
|
||||
required this.uri,
|
||||
required this.isValid,
|
||||
required this.reason,
|
||||
required this.length,
|
||||
required this.host,
|
||||
required this.path,
|
||||
required this.hasLoginVerifier,
|
||||
});
|
||||
}
|
||||
|
||||
OidcRedirectCheckResult validateOidcRedirectTarget(String redirectTo) {
|
||||
final trimmed = redirectTo.trim();
|
||||
if (trimmed.isEmpty) {
|
||||
return const OidcRedirectCheckResult(
|
||||
uri: null,
|
||||
isValid: false,
|
||||
reason: 'empty',
|
||||
length: 0,
|
||||
host: '',
|
||||
path: '',
|
||||
hasLoginVerifier: false,
|
||||
);
|
||||
}
|
||||
|
||||
Uri parsed;
|
||||
try {
|
||||
parsed = Uri.parse(trimmed);
|
||||
} catch (_) {
|
||||
return OidcRedirectCheckResult(
|
||||
uri: null,
|
||||
isValid: false,
|
||||
reason: 'parse_error',
|
||||
length: trimmed.length,
|
||||
host: '',
|
||||
path: '',
|
||||
hasLoginVerifier: false,
|
||||
);
|
||||
}
|
||||
|
||||
final scheme = parsed.scheme.toLowerCase();
|
||||
final isHttpScheme = scheme == 'http' || scheme == 'https';
|
||||
final isAbsolute = parsed.hasScheme && parsed.host.isNotEmpty;
|
||||
final isValid = isHttpScheme && isAbsolute;
|
||||
|
||||
final reason = isValid
|
||||
? 'ok'
|
||||
: (isAbsolute ? 'unsupported_scheme' : 'not_absolute');
|
||||
|
||||
return OidcRedirectCheckResult(
|
||||
uri: isValid ? parsed : null,
|
||||
isValid: isValid,
|
||||
reason: reason,
|
||||
length: trimmed.length,
|
||||
host: parsed.host,
|
||||
path: parsed.path,
|
||||
hasLoginVerifier: parsed.queryParameters.containsKey('login_verifier'),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user