go_router_auth 0.1.0 copy "go_router_auth: ^0.1.0" to clipboard
go_router_auth: ^0.1.0 copied to clipboard

A simple auth guard for GoRouter. Handles login redirect, public routes, loading state, and protected UI widgets. Framework-agnostic.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_auth/go_router_auth.dart';

/// Simple in-memory auth service for demonstration.
class AuthService extends ChangeNotifier {
  bool _isLoggedIn = false;

  bool get isLoggedIn => _isLoggedIn;

  Future<void> login(String email, String password) async {
    await Future.delayed(const Duration(seconds: 1));
    _isLoggedIn = true;
    notifyListeners();
  }

  Future<void> logout() async {
    _isLoggedIn = false;
    notifyListeners();
  }
}

void main() {
  final authService = AuthService();

  final authGuard = AuthGuard(
    isLoggedIn: () => authService.isLoggedIn,
    loginPath: '/login',
    homePath: '/dashboard',
    publicRoutes: ['/login'],
  );

  final router = GoRouter(
    initialLocation: '/dashboard',
    redirect: authGuard.redirect,
    refreshListenable: authGuard,
    routes: [
      GoRoute(
        path: '/login',
        builder: (context, state) => LoginPage(
          authService: authService,
          authGuard: authGuard,
        ),
      ),
      GoRoute(
        path: '/dashboard',
        builder: (context, state) => DashboardPage(
          authService: authService,
          authGuard: authGuard,
        ),
      ),
      GoRoute(
        path: '/profile',
        builder: (context, state) => ProfilePage(
          authService: authService,
          authGuard: authGuard,
        ),
      ),
    ],
  );

  runApp(MyApp(router: router));
}

class MyApp extends StatelessWidget {
  final GoRouter router;
  const MyApp({super.key, required this.router});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Auth Guard Demo',
      theme: ThemeData(primarySwatch: Colors.indigo),
      routerConfig: router,
    );
  }
}

// ─── Pages ──────────────────────────────────────────────────────

class LoginPage extends StatelessWidget {
  final AuthService authService;
  final AuthGuard authGuard;

  const LoginPage({
    super.key,
    required this.authService,
    required this.authGuard,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Login')),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Text(
                'Selamat datang',
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 8),
              const Text('Silakan login untuk melanjutkan'),
              const SizedBox(height: 24),
              ElevatedButton(
                onPressed: () async {
                  await authService.login('test@test.com', '123456');
                  authGuard.notify(); // GoRouter redirects to /dashboard
                },
                style: ElevatedButton.styleFrom(
                  minimumSize: const Size(double.infinity, 48),
                ),
                child: const Text('Login Demo'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class DashboardPage extends StatelessWidget {
  final AuthService authService;
  final AuthGuard authGuard;

  const DashboardPage({
    super.key,
    required this.authService,
    required this.authGuard,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Dashboard'),
        actions: [
          IconButton(
            icon: const Icon(Icons.logout),
            onPressed: () async {
              await authService.logout();
              authGuard.notify(); // GoRouter redirects to /login
            },
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Icon(Icons.check_circle, size: 64, color: Colors.green),
            const SizedBox(height: 16),
            const Text(
              'Login berhasil!',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            const Text('Ini halaman yang dilindungi'),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: () => context.push('/profile'),
              child: const Text('Ke Profile'),
            ),
          ],
        ),
      ),
    );
  }
}

class ProfilePage extends StatelessWidget {
  final AuthService authService;
  final AuthGuard authGuard;

  const ProfilePage({
    super.key,
    required this.authService,
    required this.authGuard,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Profile')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            // ProtectedRoute — user info hanya muncul jika login
            ProtectedRoute(
              authGuard: authGuard,
              child: Column(
                children: [
                  const CircleAvatar(
                    radius: 40,
                    child: Icon(Icons.person, size: 40),
                  ),
                  const SizedBox(height: 16),
                  const Text(
                    'User Profile',
                    style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                  ),
                  const Text('user@example.com'),
                ],
              ),
              unauthenticatedBuilder: (context) => const Text(
                'Silakan login untuk melihat profile',
                style: TextStyle(color: Colors.grey),
              ),
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: () => context.pop(),
              child: const Text('Kembali'),
            ),
          ],
        ),
      ),
    );
  }
}
0
likes
150
points
23
downloads

Documentation

API reference

Publisher

verified publisherciptaantaradigital.com

Weekly Downloads

A simple auth guard for GoRouter. Handles login redirect, public routes, loading state, and protected UI widgets. Framework-agnostic.

Repository (GitHub)
View/report issues

Topics

#go-router #authentication #routing #guard #navigation

License

MIT (license)

Dependencies

flutter, go_router

More

Packages that depend on go_router_auth