如何在Laravel中基于用户角色实现页面内容隐藏及权限控制
Laravel原生角色权限控制实现方案(无第三方依赖)
1. 角色基础表结构搭建
不需要复杂的多表关联,单字段即可满足你当前5类角色的需求,后续要扩展精细权限再加中间表即可:
- 给
users表新增role字段,类型设为string,存储角色标识,比如admin/doctor/patient/assistant/laboratorian,默认值可设为patient - 迁移文件示例:
Schema::table('users', function (Blueprint $table) { $table->string('role')->default('patient'); });
- 在
User模型中统一管理角色常量,加快捷角色判断方法,避免硬编码:
// app/Models/User.php class User extends Authenticatable { const ROLE_ADMIN = 'admin'; const ROLE_DOCTOR = 'doctor'; const ROLE_PATIENT = 'patient'; const ROLE_ASSISTANT = 'assistant'; const ROLE_LABORATORIAN = 'laboratorian'; // 快捷判断角色 public function hasRole(string $role): bool { return $this->role === $role; } }
2. 用Gates定义全局通用权限
Gates适合定义和特定模型无关的全局权限,比如菜单访问、页面公共区域显隐控制:
- 在
app/Providers/AuthServiceProvider.php的boot方法中注册Gates:
public function boot() { $this->registerPolicies(); // 示例:定义患者管理菜单的访问权限:仅管理员、医生、助手可访问 Gate::define('access-patient-menu', function (User $user) { return in_array($user->role, [ User::ROLE_ADMIN, User::ROLE_DOCTOR, User::ROLE_ASSISTANT ]); }); // 示例:定义检验报告查看权限:管理员、医生、检验人员、报告所属患者可查看 Gate::define('view-lab-report', function (User $user, Report $report) { return $user->hasRole(User::ROLE_ADMIN) || $user->hasRole(User::ROLE_DOCTOR) || $user->hasRole(User::ROLE_LABORATORIAN) || $user->id === $report->patient_id; }); }
3. 用Policy定义模型级操作权限
Policy专门绑定特定模型的操作权限,你要求的患者信息编辑、删除权限就用Policy实现:
- 生成绑定Patient模型的Policy,执行命令:
php artisan make:policy PatientPolicy --model=Patient - 编辑
app/Policies/PatientPolicy.php的对应方法:
// 患者信息编辑权限:管理员、负责该患者的医生、对应医生的助手可编辑 public function update(User $user, Patient $patient): bool { return $user->hasRole(User::ROLE_ADMIN) || ($user->hasRole(User::ROLE_DOCTOR) && $user->id === $patient->doctor_id) || ($user->hasRole(User::ROLE_ASSISTANT) && $user->doctor_id === $patient->doctor_id); } // 患者信息删除权限:仅管理员可删除 public function delete(User $user, Patient $patient): bool { return $user->hasRole(User::ROLE_ADMIN); }
- 必须在
AuthServiceProvider的$policies数组中绑定模型和Policy才能生效:
protected $policies = [ Patient::class => PatientPolicy::class, ];
4. 不同场景的权限调用方式
后端控制器/接口调用
- 控制器方法中直接用
authorize校验,无权限会自动抛出403异常:
public function update(Request $request, Patient $patient) { $this->authorize('update', $patient); // 后续业务逻辑 }
- 全局Gates权限校验用
Gate门面:
if (Gate::allows('access-patient-menu')) { // 对应业务逻辑 }
Blade视图显隐控制
- 用
@can指令控制菜单、按钮、页面局部的显示隐藏:
{{-- 患者管理菜单仅有权限用户可见 --}} @can('access-patient-menu') <li><a href="{{ route('patients.index') }}">患者管理</a></li> @endcan {{-- 编辑按钮仅拥有患者编辑权限的用户可见 --}} @can('update', $patient) <button>编辑患者信息</button> @endcan
- 反向控制隐藏用
@cannot指令即可。
内容的提问来源于stack exchange,提问作者Shady Hesham
相关产品推荐
相关产品推荐

