PHP项目Laravel中间件分组与别名

wen PHP项目 3

本文目录导读:

PHP项目Laravel中间件分组与别名

  1. 中间件别名
  2. 中间件分组
  3. 组合使用
  4. 自定义中间件分组示例
  5. 中间件优先级
  6. 实际应用示例
  7. 命名空间和路径
  8. 最佳实践

在 Laravel 中,中间件分组和别名是组织和管理中间件的两种重要方式,让我详细介绍一下:

中间件别名

定义别名

app/Http/Kernel.php 中定义中间件别名:

protected $middlewareAliases = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    'role' => \App\Http\Middleware\CheckRole::class, // 自定义中间件别名
    'permission' => \App\Http\Middleware\CheckPermission::class,
];

使用别名

// 在路由中使用
Route::get('/admin', function () {
    return view('admin.dashboard');
})->middleware('auth', 'role:admin');
// 或在控制器中使用
public function __construct()
{
    $this->middleware('auth');
    $this->middleware('role:admin');
}

中间件分组

定义分组

app/Http/Kernel.php 中定义中间件分组:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
    // 自定义中间件分组
    'admin' => [
        'web',
        'auth',
        'role:admin',
        \App\Http\Middleware\LogAdminActions::class,
    ],
    'user' => [
        'web',
        'auth',
        'role:user',
    ],
];

使用分组

// 在路由文件中使用
Route::middleware('admin')->group(function () {
    Route::get('/admin/dashboard', [AdminController::class, 'dashboard']);
    Route::resource('/admin/users', UserController::class);
});
// 或在路由定义时指定
Route::get('/admin/analytics', [AnalyticsController::class, 'index'])
    ->middleware('admin');
// 控制器中使用
class AdminController extends Controller
{
    public function __construct()
    {
        $this->middleware('admin');
    }
}

组合使用

多个别名和分组组合

// 1. 在路由组中使用多个中间件
Route::middleware(['auth', 'role:admin', 'permission:edit-user'])
    ->group(function () {
        Route::get('/users', [UserController::class, 'index']);
        Route::post('/users', [UserController::class, 'store']);
    });
// 2. 动态设置中间件
Route::get('/profile', function () {
    return view('profile');
})->middleware(['auth', 'verified']);
// 3. 排除某些中间件
Route::middleware('auth')
    ->except('auth.basic')
    ->group(function () {
        // 不包含 auth.basic 的路由组
        Route::get('/account', [AccountController::class, 'show']);
        Route::patch('/account', [AccountController::class, 'update']);
    });

自定义中间件分组示例

创建自定义分组逻辑

// app/Http/Kernel.php
protected $middlewareGroups = [
    // ... 默认分组
    'api.admin' => [
        'api',
        'auth:sanctum',
        'role:admin',
        'permission:api-access',
    ],
    'dashboard' => [
        'web',
        'auth',
        'role:admin,manager',
        \App\Http\Middleware\CheckMaintenanceMode::class,
    ],
];

中间件分组中的参数传递

// 在分组中传递参数
Route::middleware('role:admin,editor')->group(function () {
    Route::get('/admin/content', [ContentController::class, 'index']);
    Route::post('/admin/content', [ContentController::class, 'store']);
});

中间件优先级

// 定义中间件优先级(可选)
protected $middlewarePriority = [
    \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
    \Illuminate\Cookie\Middleware\EncryptCookies::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authenticate::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];

实际应用示例

// routes/web.php
Route::group(['middleware' => ['web', 'auth']], function () {
    // 用户相关的路由
    Route::get('/profile', [ProfileController::class, 'show']);
    Route::put('/profile', [ProfileController::class, 'update']);
});
Route::get('/admin', function () {
    return view('admin');
})->middleware(['role:admin', 'auth']);
Route::get('/api/v1/users', function () {
    return response()->json(['message' => 'Admin API']);
})->middleware(['api.admin', 'throttle:10,1']);

命名空间和路径

确保中间件类的命名空间正确:

// app/Http/Middleware/CheckRole.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class CheckRole
{
    public function handle($request, Closure $next, ...$roles)
    {
        if (!Auth::check()) {
            return redirect('login');
        }
        $userRoles = Auth::user()->roles->pluck('name')->toArray();
        if (!array_intersect($roles, $userRoles)) {
            abort(403, 'Unauthorized action.');
        }
        return $next($request);
    }
}

最佳实践

  1. 命名规范:使用语义化的名称
  2. 参数处理:使用 ...$parameters 接收可变参数
  3. 错误处理:在中间件中做好异常处理
  4. 性能考虑:避免在中间件中进行耗时操作
  5. 安全性:确保中间件逻辑的安全性

这些特性使得 Laravel 的认证、授权和请求过滤变得更加灵活和高效,通过合理使用中间件分组和别名,你可以构建出清晰、可维护的路由结构。

抱歉,评论功能暂时关闭!