You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Firebase认证实现理发师/顾客双角色访问控制

美发服务应用双角色权限控制实现方案

整个实现分4步走,直接对应你现有代码改即可:

1. 扩展Auth Provider的角色管理能力

你现有Auth类只存了认证凭证,没有角色字段,而且signup方法预留的options参数完全没用到,先补全这部分逻辑:

  • 首先在Auth类里新增角色私有字段和对外getter:
String? _userRole;
String? get userRole => _userRole;
  • 注册流程改造:原有_authenticate方法执行成功拿到_userId后,用Firebase Firestore存用户额外信息,把用户注册时选择的角色写入users/[userId]文档,固定存role: 'barber'(理发师)或role: 'customer'(顾客)两个值
  • 登录流程改造:认证成功拿到_userId后,主动请求Firestore对应用户文档,拉取role字段赋值给_userRole
  • 登出时记得把_userRole置空,所有角色字段更新后调用notifyListeners()触发UI刷新
  • 改造后的signup方法示例:
Future<void> signup(String? email, String? password, String selectedRole) async {
  await _authenticate(email!, password!, 'signupNewUser');
  // 注册成功后存角色到Firestore
  await FirebaseFirestore.instance.collection('users').doc(_userId).set({
    'email': email,
    'role': selectedRole
  });
  _userRole = selectedRole;
  notifyListeners();
}
  • 改造后的login方法示例:
Future<void> login(String? email, String? password) async {
  await _authenticate(email!, password!, 'verifyPassword');
  // 登录成功后拉取用户角色
  final userDoc = await FirebaseFirestore.instance.collection('users').doc(_userId).get();
  _userRole = userDoc.data()!['role'];
  notifyListeners();
}

2. 修复注册页的角色选择逻辑

你现有auth_screen.dart里的角色选项写的是Driver、Customer,默认值是Student,完全不符合业务,而且没有把选择器加到表单里,按下面修改:

  • 先修正角色选项常量:
var roleOptions = ['Barber', 'Customer'];
var _currentSelectedRole = "Customer";
  • 在注册模式的「确认密码」输入框下方,加一个表单内的下拉选择器,仅在Signup模式显示,示例代码:
if (_authMode == AuthMode.Signup)
  DropdownButtonFormField<String>(
    value: _currentSelectedRole,
    items: roleOptions.map((role) {
      return DropdownMenuItem(
        value: role,
        child: Text(role == 'Barber' ? '我是理发师' : '我是顾客'),
      );
    }).toList(),
    onChanged: (val) {
      setState(() {
        _currentSelectedRole = val!;
      });
    },
    onSaved: (val) {
      _authData['role'] = val!;
    },
  )
  • 注册提交时把选中的角色传给signup方法:
await Provider.of<Auth>(context, listen: false).signup(
  _authData['email'],
  _authData['password'],
  _authData['role'],
);

3. 实现多层级权限控制

不要只做单一层的控制,分三层做避免越权:

  • 入口路由控制:在main.dart的根Widget用Consumer监听Auth状态,未登录直接显示AuthScreen;已登录的话判断userRole,理发师跳理发师端首页,顾客跳顾客端首页,不要共用同一个首页
  • 路由拦截控制:在MaterialApp的onGenerateRoute回调里加校验,如果用户访问的是理发师专属路由,但当前角色是customer,直接重定向到顾客首页,防止用户手动输入路由地址越权访问
  • 页面组件控制:同一个页面内需要区分角色显示的内容,直接用角色判断包裹组件即可,比如:
// 只有理发师能看到预约管理按钮
if (Provider.of<Auth>(context, listen: false).userRole == 'Barber')
  ElevatedButton(onPressed: (){}, child: Text('预约管理'))
// 只有顾客能看到下单按钮
if (Provider.of<Auth>(context, listen: false).userRole == 'Customer')
  ElevatedButton(onPressed: (){}, child: Text('预约理发'))
  • 重要提醒:前端的控制只是体验优化,一定要在Firestore配置安全规则,比如理发师专属数据只允许role为barber的用户读写,不然懂技术的用户可以直接绕过前端限制调接口改数据

4. 可选优化:本地持久化

可以用shared_preferences把token、userId、userRole、过期时间存在本地,App冷启动的时候先读本地缓存,凭证有效的话直接拉取用户信息进入对应首页,不用每次打开都重新登录。

内容的提问来源于stack exchange,提问作者Lloyd Wingrove

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 14:09:15