You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 02:37:35