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

GoRouter认证成功后无法跳转至原始路径的问题

问题分析

你的核心问题是未在重定向到登录页时保存用户原本要访问的路径,导致登录成功后GoRouter不知道该跳回哪里。当前逻辑只处理了"未认证→登录页"的单向跳转,缺少"登录成功→原始路径"的反向跳转逻辑。

修复步骤

1. 修改重定向逻辑,保存原始路径

在redirect函数中,当检测到用户未认证且不在登录/注册页面时,将当前路径通过查询参数传递给登录页;当用户已认证且当前在登录/注册页时,跳回保存的原始路径(无则跳首页):

redirect: (context, state) {
  final authState = ref.read(authenticationListener).value;
  final isAuthenticated = authState != null;
  final isLoginPage = state.subloc == Routes.login.toPath();
  final isRegisterPage = state.subloc == p.join(Routes.login.toPath(), Routes.signUp.toPath());
  final isLoginOrRegister = isLoginPage || isRegisterPage;

  // 未认证且不在登录/注册页 → 跳转登录并携带原始路径
  if (!isAuthenticated && !isLoginOrRegister) {
    return '${Routes.login.toPath()}?redirectTo=${Uri.encodeComponent(state.subloc)}';
  }

  // 已认证但在登录/注册页 → 跳回原始路径或首页
  if (isAuthenticated && isLoginOrRegister) {
    final redirectTo = state.queryParams['redirectTo'];
    return redirectTo ?? Routes.home.toPath();
  }

  // 其他情况正常放行
  return null;
},

2. 确保认证状态变化触发重定向

你的authenticationListener已经基于ValueNotifier实现,只要登录成功后更新AuthenticationController的状态,refreshListenable就会自动触发GoRouter的重定向逻辑,无需手动调用go或push。

完整修复后的routerProvider代码
final routerProvider = Provider<GoRouter>((ref) {
  return GoRouter(
    initialLocation: Routes.home.toPath(),
    refreshListenable: ref.read(authenticationListener),
    redirect: (context, state) {
      final authState = ref.read(authenticationListener).value;
      final isAuthenticated = authState != null;
      final isLoginPage = state.subloc == Routes.login.toPath();
      final isRegisterPage = state.subloc == p.join(Routes.login.toPath(), Routes.signUp.toPath());
      final isLoginOrRegister = isLoginPage || isRegisterPage;

      // 未认证且不在登录/注册页 → 跳转登录并携带原始路径
      if (!isAuthenticated && !isLoginOrRegister) {
        return '${Routes.login.toPath()}?redirectTo=${Uri.encodeComponent(state.subloc)}';
      }

      // 已认证但在登录/注册页 → 跳回原始路径或首页
      if (isAuthenticated && isLoginOrRegister) {
        final redirectTo = state.queryParams['redirectTo'];
        return redirectTo ?? Routes.home.toPath();
      }

      // 其他情况正常放行
      return null;
    },
    routes: [
      GoRoute(
          path: Routes.login.toPath(),
          name: Routes.login.name,
          builder: (context, state) => const Login(),
          routes: [
            GoRoute(
              path: Routes.signUp.toPath(),
              name: Routes.signUp.name,
              builder: (context, state) => const SignUp(),
            )
          ]),
      GoRoute(
        path: Routes.home.toPath(),
        name: Routes.home.name,
        builder: (context, state) => const Home(),
      ),
    ],
  );
});
关键说明
  • 路径编码:用Uri.encodeComponent编码原始路径,避免特殊字符导致参数解析错误。
  • 循环重定向防护:通过判断当前页面是否为登录/注册页,防止已认证用户被反复重定向。
  • 自动跳转:依赖refreshListenable监听认证状态变化,自动触发重定向,无需在登录逻辑中手动处理跳转。

内容的提问来源于stack exchange,提问作者Saqlain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:55:16