diff --git a/app/lib/features/auth/auth_repository.dart b/app/lib/features/auth/auth_repository.dart index a25591f..8c2cd2d 100644 --- a/app/lib/features/auth/auth_repository.dart +++ b/app/lib/features/auth/auth_repository.dart @@ -68,9 +68,12 @@ class AuthRepository extends ChangeNotifier { AuthProviderKind.line, providerId: FirebaseAccountLinker.providerIds[AuthProviderKind.line]!, scopes: const ['profile', 'email'], - // LINE 앱 자동 로그인으로 넘어가면 콜백이 Custom Tab 밖에서 열려 로그인이 - // 깨진다(Android). LINE Login 공식 파라미터로 끈다. - androidParameters: const {'disable_auto_login': 'true'}, + // LINE 앱 자동 로그인으로 넘어가면 콜백이 웹 로그인 창 밖에서 열려 로그인이 + // 깨진다(Android · iOS). LINE Login 공식 파라미터로 끈다. + appParameters: const { + 'disable_auto_login': 'true', + 'disable_ios_auto_login': 'true', + }, ), ]; diff --git a/app/lib/features/auth/social_providers.dart b/app/lib/features/auth/social_providers.dart index 42db9e5..1632fcb 100644 --- a/app/lib/features/auth/social_providers.dart +++ b/app/lib/features/auth/social_providers.dart @@ -224,7 +224,7 @@ final class OidcSignInProvider implements SocialAuthProvider { this.provider, { required this.providerId, this.scopes = const [], - this.androidParameters = const {}, + this.appParameters = const {}, this.firebaseAuth, }); @@ -239,11 +239,11 @@ final class OidcSignInProvider implements SocialAuthProvider { /// KOE205 로 로그인 자체를 막는다. final List scopes; - /// Android 에서만 인가 URL 에 붙일 파라미터. Android Custom Tab 은 다른 앱으로 - /// 넘어갔다 돌아오면 콜백이 일반 Chrome 탭에서 열려 Firebase 핸들러가 - /// 「missing initial state」로 끝난다 — 앱 전환을 막는 공식 파라미터를 여기 둔다. - /// iOS 는 정상이라 건드리지 않는다. - final Map androidParameters; + /// 앱(Android · iOS)에서 인가 URL 에 붙일 파라미터. 웹 로그인 도중 제공자 앱(LINE 등)으로 + /// 넘어갔다 돌아오면 콜백이 원래 브라우저 세션 밖에서 열려 Firebase 핸들러가 + /// 「missing initial state」로 끝난다(Android 10/5 · iOS 10/11 실기기) — 앱 전환을 막는 + /// 제공자 공식 파라미터를 여기 둔다. + final Map appParameters; /// 테스트 주입용. 기본은 [fb.FirebaseAuth.instance]. final fb.FirebaseAuth? firebaseAuth; @@ -260,9 +260,7 @@ final class OidcSignInProvider implements SocialAuthProvider { for (final scope in scopes) { p.addScope(scope); } - if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) { - p.setCustomParameters(androidParameters); - } + if (!kIsWeb) p.setCustomParameters(appParameters); return p; } diff --git a/app/test/auth_oidc_test.dart b/app/test/auth_oidc_test.dart index 6094fe1..bd3aa67 100644 --- a/app/test/auth_oidc_test.dart +++ b/app/test/auth_oidc_test.dart @@ -87,16 +87,22 @@ void main() { expect((outcome as AuthFailed).code, 'E-AUTH-11'); }); - test('Android 의 LINE 은 앱 자동 로그인을 끈다 · iOS 는 파라미터 없음', () { + test('LINE 은 Android · iOS 모두 앱 자동 로그인을 끈다', () { final line = AuthRepository().providers.firstWhere( (p) => p.provider == AuthProviderKind.line, ) as OidcSignInProvider; - expect(line.authProvider.parameters, {'disable_auto_login': 'true'}); + expect(line.authProvider.parameters, { + 'disable_auto_login': 'true', + 'disable_ios_auto_login': 'true', + }); debugDefaultTargetPlatformOverride = TargetPlatform.iOS; addTearDown(() => debugDefaultTargetPlatformOverride = null); - expect(line.authProvider.parameters, isEmpty); + expect(line.authProvider.parameters, { + 'disable_auto_login': 'true', + 'disable_ios_auto_login': 'true', + }); }); testWidgets('Android: 앱으로 돌아왔는데 결과가 없으면 취소로 풀린다', (tester) async {