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

如何更简洁地检查当前用户是否拥有指定权限(自定义实现)

自定义用户权限检查的优化实现

我拥有四张表(users、permissions、roles、roles_permissions),表结构如下:

users
_______________________
| id | name | role_id |
|____|______|_________|
| 1  | John |    1    |
|____|______|_________|


     roles
______________
| id | name  |
|____|_______|
| 1  | admin |
|____|_______|


      permissions
____________________
| id | permission  |
|____|_____________|
| 1  | view-posts  |
|____|_____________|


        roles_permissions
________________________________
| id | permission_id | role_id |
|____|_______________|_________|
| 1  |       1       |    1    |
|____|_______________|_________|

我想要检查当前用户是否拥有如view-posts这类指定权限,已在Permission.php模型中实现了以下方法:

public function checkPermission($permission){ 
    $role = Auth()->user()->role_id;
    $id = $this->select('permissions.id')->join('role_permissions as rp', 'rp.permission_id', 'permissions.id')->where('rp.role_id', $role)->where('permission', $permission)->get()->toArray();
    return $id ? true : false; 
}

调用方式如下:

$permission = new permission();
$check = $permission->checkPermission('view-posts');

请问是否有更简洁/更优的实现方式?

注:请勿推荐权限包,我因特定需求需使用自定义方法


优化方案

1. 直接用exists()简化查询逻辑

原方法需要获取数据转数组后判断,不如直接让数据库返回是否存在的布尔值,性能更高,代码更简洁:

// Permission.php
public function checkPermission($permission)
{
    $roleId = Auth()->user()->role_id;
    
    return $this->join('roles_permissions as rp', 'rp.permission_id', '=', 'permissions.id')
                ->where('rp.role_id', $roleId)
                ->where('permissions.permission', $permission)
                ->exists();
}

2. 将方法迁移到User模型,调用更直观

权限检查是针对当前用户的,把方法放到User.php里更符合逻辑,无需实例化Permission模型:

// User.php
public function hasPermission($permission)
{
    return $this->join('roles', 'users.role_id', '=', 'roles.id')
                ->join('roles_permissions as rp', 'roles.id', '=', 'rp.role_id')
                ->join('permissions', 'permissions.id', '=', 'rp.permission_id')
                ->where('users.id', $this->id)
                ->where('permissions.permission', $permission)
                ->exists();
}

调用时直接用:

$check = Auth()->user()->hasPermission('view-posts');

如果已经在User模型定义了和Role的关联(public function role() { return $this->belongsTo(Role::class); }),还可以简化成:

// User.php
public function hasPermission($permission)
{
    return $this->role()
                ->join('roles_permissions as rp', 'roles.id', '=', 'rp.role_id')
                ->join('permissions', 'permissions.id', '=', 'rp.permission_id')
                ->where('permissions.permission', $permission)
                ->exists();
}

3. 利用模型关联实现内存级检查(适合频繁调用场景)

提前通过关联加载用户的权限,后续检查直接在内存中判断,避免重复查库:

// User.php
public function role()
{
    return $this->belongsTo(Role::class);
}

// Role.php
public function permissions()
{
    return $this->belongsToMany(Permission::class, 'roles_permissions');
}

// User.php中的权限检查方法
public function hasPermission($permission)
{
    // 首次调用会加载关联,后续直接用缓存的数据
    return $this->role->permissions->pluck('permission')->contains($permission);
}

调用前可以预加载关联减少查询次数:

// 比如在控制器中
$user = Auth()->user()->load('role.permissions');
$check = $user->hasPermission('view-posts');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:20:27