qlevar_router icon indicating copy to clipboard operation
qlevar_router copied to clipboard

AuthMiddleware in children of QRoute.withChild not work

Open min23asdw opened this issue 1 year ago • 2 comments

on app_routes.dart

  final routes = <QRoute>[
    WebRoutes().route, // Add the dashboard routes
  ];

on web_router.dart

class WebRoutes {
  final route = QRoute.withChild(
      name: "web",
      path: '/',
      initRoute: '/homePage',
      builderChild: (router) => WebPage(router: router),
      middleware: [],
      children: [
        QRoute(
          path: '/homePage',
          builder: () => MyHomePage(),
        ),
        QRoute(
            path: '/CampaignDetail',
            builder: () => NotFoundView(),
            children: [
              QRoute(
              )
            ]),
        QRoute(
            path: '/profile',
            middleware: [
              AuthMiddleware(),
            ],
            builder: () => Profile()
        ),
        QRoute(
          path: '/login',
          builder: () => const LoginView(),
        ),
      ]);
}         
class AuthMiddleware extends QMiddleware {
  final authService = Get.find<AuthService>();

  @override
  Future<String?> redirectGuard(String path) async {

    if (authService.isAuth) {
      return null;
    }
    return '/login';
  }
}

if I click button in website that QR.to profile [ www.xxx.com/profile] if user not login it will redirect to /login [ www.xxx.com/login ] can work normally

but if I enter [www.xxx.com/profile ] in browser url bar that not Init Page
my web redirect to /login [ www.xxx.com/login ] but LoginView() not load and show

image

min23asdw avatar Jun 21 '23 14:06 min23asdw

I found how to solve

when i remove QR.setUrlStrategy(); in main.dart image

it work!!!! LoginView() is loaded

it mean setUrlStrategy have something wrong?

min23asdw avatar Jun 21 '23 16:06 min23asdw

I found way to solve with still use setUrlStrategy becase in root stack tree if user enter web by www.xxx.com/profile , that are not root of route the middle will display key[0] web (root route ) on top of the stack

that mean web don't have anything to display it will display Init page -> loading problem image

by add QR.navigator.switchTo('/login'); in middleware

class AuthMiddleware extends QMiddleware {
  final authService = Get.find<AuthService>();
  @override
  Future<String?> redirectGuard(String path) async {
    print('authService  run');
    if (authService.isAuth) {
      return null;
    }
    QR.navigator.switchTo('/login');
    return '/login';
  }
}

image

I not sure it a good way but it work

min23asdw avatar Jun 24 '23 12:06 min23asdw

Using this example, I could not reproduce the problem

import 'package:flutter/material.dart';
import 'package:qlevar_router/qlevar_router.dart';

void main() {
  QR.setUrlStrategy();
  runApp(const MyApp());
}

var isAuth = false;

class AuthMiddleware extends QMiddleware {
  @override
  Future<String?> redirectGuard(String path) async {
    if (isAuth) {
      return null;
    }
    return '/login';
  }
}

class Dashboard extends StatelessWidget {
  final QRouter router;
  const Dashboard(this.router, {super.key});
  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text('Dashboard'),
          centerTitle: true,
        ),
        body: Row(
          children: [
            SizedBox(
              width: MediaQuery.of(context).size.width * 0.2,
              child: const Sidebar(),
            ),
            Expanded(flex: 4, child: router)
          ],
        ),
      );
}

class Sidebar extends StatelessWidget {
  const Sidebar({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.grey.shade800,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          ListTile(
            title: const Text('homePage'),
            onTap: () => QR.to('/homePage'),
          ),
          ListTile(
            title: const Text('profile'),
            onTap: () => QR.to('/profile'),
          ),
          ListTile(
            title: const Text('login'),
            onTap: () => QR.to('/login'),
          )
        ],
      ),
    );
  }
}

class DashboardChild extends StatelessWidget {
  final String name;
  final Color color;
  const DashboardChild(this.name, this.color, {super.key});
  @override
  Widget build(BuildContext context) {
    return Container(
      color: color,
      child: Center(
        child: Text(name, style: const TextStyle(fontSize: 20)),
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final routes = [
      QRoute.withChild(
          name: "web",
          path: '/',
          initRoute: '/homePage',
          builderChild: (c) => Dashboard(c),
          children: [
            QRoute(
                path: '/homePage',
                builder: () =>
                    DashboardChild('homePage', Colors.grey.shade900)),
            QRoute(
                path: '/profile',
                middleware: [
                  AuthMiddleware(),
                ],
                builder: () => DashboardChild('profile', Colors.grey.shade700)),
            QRoute(
                path: '/login',
                builder: () => DashboardChild('login', Colors.grey.shade500)),
          ]),
    ];
    return MaterialApp.router(
      routeInformationParser: const QRouteInformationParser(),
      routerDelegate: QRouterDelegate(routes),
      theme: ThemeData.dark(),
    );
  }
}

feel free to reopen if the problem still exists

SchabanBo avatar Jul 23 '24 06:07 SchabanBo