Proper route guarding implementation with auto_route

Viewed 809

I am trying to understand how guarding works, my setup is as follows:

router

@AdaptiveAutoRouter(
  replaceInRouteName: 'Page,Route',
  routes: <AutoRoute>[
    AutoRoute(
      page: LoginPage,
      initial: true,
      path: '/login',
    ),
    AutoRoute(page: HomePage, path: '/home', guards: [AuthGuard]),
   
  ],
)
class $AppRouter {}

guard

class AuthGuard extends AutoRouteGuard {
  //from context.watch<AuthService>().isAuthenticated
  AuthGuard({required this.isAuthenticated});
  final bool isAuthenticated;

  @override
  void onNavigation(NavigationResolver resolver, StackRouter router) {
    if (isAuthenticated) {
      resolver.next(isAuthenticated);
    } else {
      router.push(LoginRoute());
      router.popForced();
      // resolver.next();
    }
  }
}

service

class AuthService extends ChangeNotifier {
  bool isAuthenticated = false;

  login() {
    isAuthenticated = true;
    notifyListeners();
  }

  logout() {
    isAuthenticated = false;
    notifyListeners();
  }
}

screens

class LoginPage extends StatelessWidget {
  const LoginPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Login Page'),
      ),
      body: Center(
        child: Column(
          children: [
            ElevatedButton(
                onPressed: () {
                  context.read<AuthService>().login();
                  context.pushRoute(HomeRoute());
                },
                child: Text('Authenticate Me')),
            ElevatedButton(
                onPressed: () {
                  context.pushRoute(HomeRoute());
                },
                child: Text('Go Home')),
          ],
        ),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Center(
        child: ElevatedButton(
            onPressed: () {
              context.read<AuthService>().logout();
            },
            child: Text('Uauthenticate Me')),
      ),
    );
  }
}

Now clicking Go Home button prevents me from navigating to the home page which is correct, however when I click Authenticate Me button, it does not route me to the HomeRoute but instead I get a blank screen while the path still shows /login.

1 Answers

Sorry I don't see where you pass your argument isAuthenticated, maybe this is the issue ? I've seen you gave up auto_route in the comment, I post this answer for you or those who face issue to handle guard on provider.

Provider

You can get the context to get your provider from your guard.


  @override
  void onNavigation(NavigationResolver resolver, StackRouter router) async {
   final context = router.navigatorKey.currentContext;
   context.read< AuthService>()

   // Use your provider

}

Related