Flutter web redirect user if not authentiacted

1,905

Solution 1

Use middleware for check if user is authenticated or not

GetMaterialApp(
      initialBinding: InitialBinding(),
      debugShowCheckedModeBanner: false,
      theme: CustomTheme().getLightTheme,
      themeMode: ThemeMode.light,
      title: "----------",
      initialRoute: "/dashboard",
      unknownRoute: GetPage(name: "/notfound", page: () => NotFoundPage()),
      getPages: [
        GetPage(name: "/login", page: () => Root()),
        GetPage(name: "/dashboard", page: () => Dashboard(), middleware: [AuthMiddleware()]),
      ],
    ),

class AuthMiddlware extends Middlware {
   RouteSetting? redirect(String? route) => !isAuthenticated ? RouteSetting(name="/login") : null;
}

Solution 2

If the user requests an arbitrary page within your web app, then you may want to intercept with the login page before continuing to the requested page. You can do this by passing a return url to the login page...

main.dart

GetMaterialApp(
  ...
  initialRoute: "/dashboard",
  getPages: [
    GetPage(name: "/login", page: () => Root()),
    GetPage(
      name: "/dashboard", 
      page: () => Dashboard(), 
      middlewares: [AuthMiddleware()]
    ),
  ],
),

class AuthMiddleware extends GetMiddleware {
  RouteSettings? redirect(String? route) {
    String returnUrl = Uri.encodeFull(route ?? '');
    return !isAuthenticated
      ? RouteSettings(name: "/login?return=" + returnUrl)
      : null;
  }
}

Then in your login page, after logging in you can direct back to where the original request intended...

login.dart

    //after successful login...
    String returnUrl = Get.parameters['return'] ?? '/';
    Get.offAllNamed(returnUrl);
Share:
1,905
Lars
Author by

Lars

Updated on December 31, 2022

Comments

  • Lars
    Lars over 1 year

    I have a GetMaterialApp with named routes to be used in Flutter web for a dashboard project. However, I am struggling to check whether the user is authenticated and redirect the user depending on the auth state. This is my App Code:

    GetMaterialApp(
          initialBinding: InitialBinding(),
          debugShowCheckedModeBanner: false,
          theme: CustomTheme().getLightTheme,
          themeMode: ThemeMode.light,
          title: "----------",
          initialRoute: "/login",
          unknownRoute: GetPage(name: "/notfound", page: () => NotFoundPage()),
          getPages: [
            GetPage(name: "/login", page: () => Root()),
            GetPage(name: "/dashboard", page: () => Dashboard()),
          ],
        ),
    

    I am using GetX to handle the authentication state. Therefore, I have access to the authentication state throughout the web app. The Root widget consists of a simple Obx to check the authentication state and send the user to the dashboard:

    return Obx(() => (Get.find<AuthController>().loggedIn) ? Dashboard() : LoginScreen());
    

    Sadly, that does not do the trick, as the url does not change, simply the content does. The url remains at /login.

    I could simply call Get.toNamed("dashboard") when the user is logged in, but then the dashboard page would be exposed to the url, allowing the user to reach the /dashboard url even if he is not logged in.

    I also do not want to create a check in every Widget or page I create, since that would be inefficient. Is there a way to check whether the user is logged in and, if not, redirect the user to the login page on every url entered?

    Example:

    Is there a way to generally check the auth-state and redirect the user accordingly using GetX?

    Side Note: I am able to get the correct authentication state every time, that is not the problem, as I use GetX.

    Short Summary: Is it possible to check the auth state outside the actual widget (e.g. in the GetMaterialApp) and redirect any not-authenticated users to the login page, even if they type in the /dashboard url?

  • Lars
    Lars over 2 years
    Thanks a lot! I just needed to change Middleware to GetMiddleware and RouteSetting to RouteSettings :)