79552097

Date: 2025-04-03 05:50:08
Score: 0.5
Natty:
Report link

1. Decode the JWT Token and Extract the User Role

Use the jwt_decoder package to extract the user's role from the token.

import 'package:jwt_decoder/jwt_decoder.dart';

String getUserRole(String token) {
  Map<String, dynamic> decodedToken = JwtDecoder.decode(token);
  return decodedToken['role'] ?? 'guest'; // Ensure a default role
}

2. Create a Role-Based Route Guard

Define a middleware function that restricts access based on the user's role.

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:stockhive_mobile/screen/auth/login_page.dart';
import 'package:stockhive_mobile/screen/admin/departements/Departmentad.dart';
import 'package:stockhive_mobile/screen/collaborator/collaborator_dashboard.dart';
import 'package:stockhive_mobile/screen/user/user_dashboard.dart';
import 'package:jwt_decoder/jwt_decoder.dart';

class RoleBasedRoute extends StatelessWidget {
  final Widget adminScreen;
  final Widget collaboratorScreen;
  final Widget userScreen;
  final Widget defaultScreen;

  RoleBasedRoute({
    required this.adminScreen,
    required this.collaboratorScreen,
    required this.userScreen,
    required this.defaultScreen,
  });

  Future<String> _getUserRole() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? token = prefs.getString('jwtToken');

    if (token == null || JwtDecoder.isExpired(token)) {
      return 'guest';
    }

    Map<String, dynamic> decodedToken = JwtDecoder.decode(token);
    return decodedToken['role'] ?? 'guest';
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: _getUserRole(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return Scaffold(body: Center(child: CircularProgressIndicator()));
        }

        String role = snapshot.data!;
        if (role == 'admin') {
          return adminScreen;
        } else if (role == 'collaborator') {
          return collaboratorScreen;
        } else if (role == 'user') {
          return userScreen;
        } else {
          return defaultScreen;
        }
      },
    );
  }
}

3. Modify generateRoute in AppRouter

Now, update the router to check for roles before navigating.

static Route<dynamic> generateRoute(RouteSettings settings) {
  switch (settings.name) {
    case '/admin-dashboard':
      return MaterialPageRoute(
        builder: (_) => RoleBasedRoute(
          adminScreen: DepartmentManagementPage(),
          collaboratorScreen: LoginPage(),
          userScreen: LoginPage(),
          defaultScreen: LoginPage(),
        ),
      );

    case '/collaborator-dashboard':
      return MaterialPageRoute(
        builder: (_) => RoleBasedRoute(
          adminScreen: LoginPage(),
          collaboratorScreen: CollaboratorDashboard(),
          userScreen: LoginPage(),
          defaultScreen: LoginPage(),
        ),
      );

    case '/user-dashboard':
      return MaterialPageRoute(
        builder: (_) => RoleBasedRoute(
          adminScreen: LoginPage(),
          collaboratorScreen: LoginPage(),
          userScreen: UserDashboard(),
          defaultScreen: LoginPage(),
        ),
      );

    default:
      return _errorRoute();
  }
}

4. Save JWT Token After Login

Modify your authentication flow to store the token in SharedPreferences.

import 'package:shared_preferences/shared_preferences.dart';

Future<void> saveToken(String token) async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  await prefs.setString('jwtToken', token);
}

5. Auto-Redirect Users Based on Role in SplashScreen

Modify SplashScreen to check the role and redirect accordingly.

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:jwt_decoder/jwt_decoder.dart';

class SplashScreen extends StatefulWidget {
  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    _navigateToDashboard();
  }

  Future<void> _navigateToDashboard() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? token = prefs.getString('jwtToken');

    if (token == null || JwtDecoder.isExpired(token)) {
      Navigator.pushReplacementNamed(context, '/login');
      return;
    }

    Map<String, dynamic> decodedToken = JwtDecoder.decode(token);
    String role = decodedToken['role'] ?? 'guest';

    if (role == 'admin') {
      Navigator.pushReplacementNamed(context, '/admin-dashboard');
    } else if (role == 'collaborator') {
      Navigator.pushReplacementNamed(context, '/collaborator-dashboard');
    } else if (role == 'user') {
      Navigator.pushReplacementNamed(context, '/user-dashboard');
    } else {
      Navigator.pushReplacementNamed(context, '/login');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: CircularProgressIndicator()),
    );
  }
}

Conclusion

With this setup:

This method ensures secure role-based authentication in Flutter using JWT tokens.

Reasons:
  • Blacklisted phrase (1): ToDas
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: Kartik Patadiya