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

如何为Laravel路由添加自定义acl()方法简化权限控制

自定义Laravel路由ACL快捷方法实现

问题背景

我维护着一个ACL服务,包含PermissionEnum权限枚举类,公司、角色、权限采用多层关联结构存储。业务涉及大量资源(分支机构、服务、技师、用户、统计数据等),每个路由端点都需要集成ACL中间件做权限校验。

目前的路由写法过于繁琐:

Route::post('/', [UserController::class, 'create'])->middleware('acl:'.PermissionEnum::USER_CREATE->value)->name('create');
Route::post('/', [MasterCreationController::class, 'create'])->middleware('acl:'.PermissionEnum::MASTER_CREATE->value)->name('create');

希望简化为链式调用的acl()方法,直接传入权限枚举即可自动添加中间件:

Route::post('/', [UserController::class, 'create'])->acl(PermissionEnum::USER_CREATE)->name('create');
Route::post('/', [MasterCreationController::class, 'create'])->acl(PermissionEnum::MASTER_CREATE)->name('create');

由于需要配置约300个带独立权限的端点,必须实现这个简化方案,要求自定义方法支持链式调用,返回Router实例。

实现方案

方式一:路由宏(推荐,轻量简洁)

Laravel自带的路由宏机制可以快速扩展路由方法,无需重写门面或核心服务类。在App\Providers\RouteServiceProvider的boot方法中添加以下代码:

use Illuminate\Routing\Router;
use App\Enums\PermissionEnum; // 替换为你的权限枚举实际命名空间

public function boot()
{
    parent::boot();

    // 注册acl路由宏
    Router::macro('acl', function (PermissionEnum $permission) {
        // 自动拼接中间件参数并添加,返回当前路由实例支持链式调用
        return $this->middleware('acl:' . $permission->value);
    });
}

方式二:扩展路由类(适合复杂扩展需求)

如果后续需要对路由逻辑做更多定制,可以创建自定义路由类继承Laravel原生Router:

  1. 创建自定义路由类:
namespace App\Routing;

use Illuminate\Routing\Router as BaseRouter;
use App\Enums\PermissionEnum;

class Router extends BaseRouter
{
    /**
     * 为路由添加ACL权限校验中间件
     * @param PermissionEnum $permission
     * @return $this
     */
    public function acl(PermissionEnum $permission)
    {
        return $this->middleware('acl:' . $permission->value);
    }
}
  1. 在路由服务提供者中绑定自定义路由类:
    在App\Providers\RouteServiceProvider的register方法中替换默认路由实例:
use App\Routing\Router;
use Illuminate\Contracts\Routing\Registrar;

public function register()
{
    $this->app->bind(Registrar::class, Router::class);
}

使用方式

两种方式实现后,都可以直接按预期写法编写路由:

Route::post('/', [UserController::class, 'create'])->acl(PermissionEnum::USER_CREATE)->name('create');
Route::post('/', [MasterCreationController::class, 'create'])->acl(PermissionEnum::MASTER_CREATE)->name('create');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 20:42:21