Laravel 13 中间件新特性详解
摘要
Laravel 13 对中间件系统进行了增强,提供了更灵活的中间件定义和使用方式。本文将深入讲解 Laravel 13 的中间件新特性,包括:
- 中间件属性详解
- 中间件组与优先级
- 终止中间件
- 中间件参数
- 实战案例与最佳实践
本文适合希望掌握 Laravel 13 中间件新特性的开发者。
1. 中间件属性
1.1 类级别中间件
1 2 3 4 5 6 7
| use Illuminate\Routing\Attributes\Controllers\Middleware;
#[Middleware('auth')] class DashboardController extends Controller { }
|
1.2 方法级别中间件
1 2 3 4 5 6 7 8 9 10 11 12 13
| class UserController extends Controller { #[Middleware('auth')] public function profile() { } public function public() { } }
|
1.3 多个中间件
1 2 3 4 5
| #[Middleware(['auth', 'verified', 'admin'])] class AdminController extends Controller { }
|
1.4 中间件参数
1 2 3 4 5 6 7 8 9 10 11
| #[Middleware('throttle:60,1')] class ApiController extends Controller { }
#[Middleware('role:admin,editor')] class ContentController extends Controller { }
|
2. 自定义中间件
2.1 创建中间件
1
| php artisan make:middleware CheckAge
|
2.2 中间件实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php
namespace App\Http\Middleware;
use Closure; use Illuminate\Http\Request;
class CheckAge { public function handle(Request $request, Closure $next) { if ($request->age < 18) { return redirect('home'); } return $next($request); } }
|
2.3 后置中间件
1 2 3 4 5 6 7 8 9 10 11
| class AfterMiddleware { public function handle(Request $request, Closure $next) { $response = $next($request); return $response; } }
|
2.4 终止中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class TerminatingMiddleware { public function handle(Request $request, Closure $next) { return $next($request); } public function terminate(Request $request, $response) { Log::info('Request completed', [ 'url' => $request->fullUrl(), 'status' => $response->status(), ]); } }
|
3. 中间件参数
3.1 定义参数
1 2 3 4 5 6 7 8 9 10 11
| class RoleMiddleware { public function handle(Request $request, Closure $next, ...$roles) { if (!in_array($request->user()->role, $roles)) { abort(403); } return $next($request); } }
|
3.2 使用参数
1 2 3 4 5
| #[Middleware('role:admin,editor')] public function admin() { }
|
4. 中间件组
4.1 定义组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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, ], 'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ];
|
4.2 使用组
1 2 3 4 5 6 7 8 9 10 11
| #[Middleware('web')] class WebController extends Controller { }
#[Middleware('api')] class ApiController extends Controller { }
|
5. 中间件优先级
5.1 全局优先级
1 2 3 4 5 6 7 8 9 10
| protected $middlewarePriority = [ \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class, \Illuminate\Routing\Middleware\ThrottleRequests::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ];
|
5.2 排除中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #[Middleware('auth')] class UserController extends Controller { public function index() { } #[Middleware(except: ['auth'])] public function public() { } }
|
6. 实战案例
6.1 API 限流中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php
namespace App\Http\Middleware;
use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Cache;
class RateLimitByUser { public function handle(Request $request, Closure $next, int $maxAttempts = 60, int $decayMinutes = 1) { $key = 'rate_limit:' . $request->user()->id; $attempts = Cache::get($key, 0); if ($attempts >= $maxAttempts) { return response()->json([ 'message' => 'Too many requests', ], 429); } Cache::put($key, $attempts + 1, now()->addMinutes($decayMinutes)); return $next($request); } }
|
6.2 日志中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?php
namespace App\Http\Middleware;
use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log;
class RequestLogger { public function handle(Request $request, Closure $next) { $startTime = microtime(true); $response = $next($request); $duration = round((microtime(true) - $startTime) * 1000, 2); Log::channel('requests')->info('Request', [ 'method' => $request->method(), 'url' => $request->fullUrl(), 'status' => $response->status(), 'duration_ms' => $duration, 'user_id' => $request->user()?->id, ]); return $response; } }
|
6.3 CORS 中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?php
namespace App\Http\Middleware;
use Closure; use Illuminate\Http\Request;
class Cors { public function handle(Request $request, Closure $next) { $response = $next($request); $response->headers->set('Access-Control-Allow-Origin', '*'); $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization'); return $response; } }
|
7. 最佳实践
7.1 中间件命名
1 2 3 4 5 6 7 8 9 10
| CheckAge Authenticate VerifyCsrfToken RateLimitRequests
AgeCheck Auth Csrf
|
7.2 中间件职责
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class CheckAge { public function handle($request, Closure $next) { } }
class CheckAgeAndRole { public function handle($request, Closure $next) { } }
|
8. 总结
Laravel 13 的中间件新特性提供了更灵活的中间件管理:
- 中间件属性:声明式中间件配置
- 中间件参数:灵活的参数传递
- 中间件组:批量管理中间件
- 终止中间件:响应后处理
参考资料