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

Flutter Web使用go_router登录后重定向异常:isLoggedIn始终为false

问题排查与修复方案

你的问题核心是登录成功后,GoRouter的redirect方法中authState.isLoggedIn仍为false,主要可能是以下几个原因:

1. AuthProvider实例不一致

如果生成路由时传入的AuthProvider实例,和登录页面中使用的不是同一个全局实例,就会导致路由监听的状态没有更新。必须确保整个App中使用的是同一个AuthProvider实例。

修复方式:
通过Provider将AuthProvider全局注入,生成路由时从全局Provider获取实例,而非手动创建新实例:

// main.dart
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => AuthProvider(),
      child: MyApp(),
    ),
  );
}

// 路由生成函数修改为从Provider获取实例
GoRouter routerGenerator(BuildContext context) {
  final authState = Provider.of<AuthProvider>(context, listen: false);
  return GoRouter(
    initialLocation: Routes.login,
    refreshListenable: authState,
    redirect: (state) {
      final isOnLogin = state.location == Routes.login;
      final isOnSignUp = state.location == Routes.signup;
      final isLoggedIn = authState.isLoggedIn;

      if (!isOnLogin && !isOnSignUp && !isLoggedIn) return Routes.login;
      if ((isOnLogin || isOnSignUp) && isLoggedIn) return Routes.home;
      return null;
    },
    routes: [
      GoRoute(
        name: Routes.home,
        path: '/Dashboard',
        pageBuilder: (context, state) => MaterialPage<void>(
          key: state.pageKey,
          child: Home(),
        ),
      ),
      // 补充登录、注册路由定义
      GoRoute(
        name: Routes.login,
        path: '/login',
        pageBuilder: (context, state) => MaterialPage<void>(
          key: state.pageKey,
          child: LoginPage(),
        ),
      ),
      GoRoute(
        name: Routes.signup,
        path: '/signup',
        pageBuilder: (context, state) => MaterialPage<void>(
          key: state.pageKey,
          child: SignUpPage(),
        ),
      ),
    ],
  );
}

2. 状态更新未正确通知监听者

虽然你在login方法中调用了notifyListeners(),但loggedIn setter本身没有触发通知,后续如果在其他地方修改loggedIn时容易遗漏通知。建议将通知逻辑整合到setter中:

修复AuthProvider:

class AuthProvider extends ChangeNotifier {
  bool _isLoggedIn = false;
  bool get isLoggedIn => _isLoggedIn;

  set loggedIn(bool value) {
    _isLoggedIn = value;
    notifyListeners(); // 赋值时自动通知监听者
  }
  
  ApiBaseHelper _helper = ApiBaseHelper();

  Future<Map<String, dynamic>> login(String email, String password) async {
      var response = await _helper.post(
        'Authentication/Login', 
        LoginVM(username: email, password: password, otp: '')
      );

      this.loggedIn = true;
      // 这里无需再手动调用notifyListeners(),setter已处理
      return response;
  }
}

3. 登录操作未等待异步完成

登录按钮点击时,必须确保await登录异步操作完成,保证状态更新后再触发路由刷新:

登录页面示例:

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final authProvider = Provider.of<AuthProvider>(context);
    return Scaffold(
      body: ElevatedButton(
        onPressed: () async {
          // 等待登录请求完成,确保状态更新
          await authProvider.login('your-email', 'your-password');
          // 无需手动跳转,GoRouter的redirect会自动处理
        },
        child: const Text('登录'),
      ),
    );
  }
}

额外检查

  • 确认Routes.login、Routes.signup的字符串值和路由定义中的path完全一致,避免因路径不匹配导致判断错误。
  • 确保refreshListenable: authState已正确设置,这样AuthProvider状态变化时会触发GoRouter重新执行redirect逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:55:18