Flutter集成Supabase谷歌认证后,DeepLink跳转Go_router路由异常
问题分析与解决方案
核心问题是Supabase OAuth回调返回的DeepLink包含URL片段(#后面的access_token等参数),GoRouter默认不会将片段内容解析为路由的一部分,导致回调后无法匹配到正确路由,停留在登录页或出现路由错误。
解决方案步骤
1. 添加专门的OAuth回调路由
在app-router.dart中新增一个/login-callback路由,专门处理Supabase的认证回调,不需要渲染UI,仅负责处理认证后的导航:
final GoRouter appRouter = GoRouter( debugLogDiagnostics: true, initialLocation: "/", navigatorKey: _rootNavigatorKey, // 新增redirect逻辑,处理认证状态路由跳转 redirect: (context, state) { final authState = context.read<AppRootCubit>().state; final isAuthenticated = authState.isAuthenticated; final isCallbackPage = state.location.startsWith("/login-callback"); // 回调页面不做重定向,留待页面内部处理 if (isCallbackPage) return null; // 未认证且不在登录页,跳转到登录页 if (!isAuthenticated && state.location != "/signin") { return "/signin"; } // 已认证且在启动/登录页,跳转到首页 if (isAuthenticated && (state.location == "/" || state.location == "/signin")) { return "/team-home"; } return null; }, routes: [ // 原启动页路由保留 GoRoute( parentNavigatorKey: _rootNavigatorKey, path: "/", builder: (context, state) => const SplashScreenPage(), ), // 新增OAuth回调路由 GoRoute( parentNavigatorKey: _rootNavigatorKey, path: "/login-callback", builder: (context, state) { // 延迟处理,确保Supabase完成认证状态更新 WidgetsBinding.instance.addPostFrameCallback((_) { final session = Supabase.instance.client.auth.currentSession; final cubit = context.read<AppRootCubit>(); if (session != null) { cubit.updateAuthState(true); context.go("/team-home"); // 认证成功跳转到首页 } else { cubit.updateAuthState(false); context.go("/signin"); // 认证失败返回登录页 } }); // 返回启动页避免空白闪烁 return const SplashScreenPage(); }, ), // 原其他路由保持不变... ], );
2. 修改Supabase回调地址
在auth_repository.dart中,将redirectTo改为直接指向回调路由,不要加末尾斜杠:
@override Future<void> signinWithGoogle() async { var res = await _supabase.client.auth.signInWithOAuth( Provider.google, redirectTo: kIsWeb ? null : 'io.supabase.launchlabnus://login-callback', ); if (!res) { throw const Failure.badRequest(); } }
3. 保持AndroidManifest配置不变
当前AndroidManifest中的DeepLink配置已经能正确匹配回调地址,无需修改:
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="io.supabase.launchlabnus" /> </intent-filter>
为什么之前的尝试失败?
- 直接用初始路由
/接收回调:GoRouter会尝试匹配/login-callback/#...,但无对应路由,因此停留在之前的登录页 - 修改为
/splash路由:回调地址变为/login-callback/splash/#...,GoRouter会忽略#后的片段,尝试匹配/splash,但原路由配置中没有该路径,导致匹配错误
内容的提问来源于stack exchange,提问作者jmsandiegoo
相关产品推荐
相关产品推荐

