在 Flutter 中使用 bloc 管理身份验证的最佳方式

best way to manage auth with bloc in Flutter

提问人:Med Oussema Zaier 提问时间:11/18/2023 更新时间:11/18/2023 访问量:37

问:

我正在开发一个 Flutter 应用程序,它具有带有底部导航栏的复杂 UI,其中包括五个不同的页面。在这些页面中,一个不需要身份验证,而其余页面需要用户身份验证才能显示内容:

如果用户拥有令牌:显示内容。 否则:显示登录页面,允许用户访问创建帐户页面。

我在 Flutter 中使用 Bloc 管理此功能的尝试没有成功,特别是使用这些页面中的共享 Bloc 实例。

我将非常感谢有关有效实施 Bloc 架构以处理此导航设置中跨多个页面的身份验证的任何指导或建议。感谢您的帮助!

颤振 集团

评论

0赞 Raphael Sauer 11/18/2023
如果您共享您的集团文件(或至少它们的模板),这将很有帮助。

答:

1赞 pixel 11/18/2023 #1

根据我的经验,我设计了一个管理用户身份验证状态的方法。Bloc 将根据用户是否经过身份验证发出不同的状态。authentication Bloc

// States
abstract class AuthenticationState {}

class AuthenticatedState extends AuthenticationState {
  // User details or tokens
}

class UnauthenticatedState extends AuthenticationState {}

// Events
abstract class AuthenticationEvent {}

class CheckAuthenticationEvent extends AuthenticationEvent {}

class LogoutEvent extends AuthenticationEvent {}

// Bloc
class AuthenticationBloc
    extends Bloc<AuthenticationEvent, AuthenticationState> {
  AuthenticationBloc() : super(UnauthenticatedState()) {
    on<CheckAuthenticationEvent>((event, emit) {
      // Check authentication status 
      bool isAuthenticated = /* logic to check authentication */;

      if (isAuthenticated) {
        emit(AuthenticatedState());
      } else {
        emit(UnauthenticatedState());
      }
    });

    on<LogoutEvent>((event, emit) {
      // Logout logic
      emit(UnauthenticatedState());
    });
  }
}

将包装 with 以在整个应用程序中共享单个 bloc 实例。MaterialAppBlocProvider

class MyApp extends StatelessWidget {
  late final AuthenticationBloc _authenticationBloc;

  @override
  void initState() {
    super.initState();
    _authenticationBloc = AuthenticationBloc();
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => _authenticationBloc,
      child: MaterialApp(
        title: 'Application',
        home: HomePage(),
      ),
    );
  }

  @override
  void dispose() {
    _authenticationBloc.close();
    super.dispose();
  }
}

并将在需要身份验证的所有四个屏幕中使用,如下所示

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<AuthenticationBloc, AuthenticationState>(
      builder: (context, state) {
        if (state is AuthenticatedState) {
          // Content for authenticated users
          return AuthenticatedContent();
        } else {
          // Login page for unauthenticated users
          // If you wanna navigate to login page than do it from BlocListner.
          return LoginPage();
        }
      },
    );
  }
}

最后,当用户从导航栏更改页面时,将调用事件,如下所示:CheckAuthenticationEvent

BlocProvider.of<AuthenticationBloc>(context).add(CheckAuthenticationEvent());