laravel教程第7课: 全局中间件和路由中间件
导航
- laravel教程第2课: 容器
- laravel教程第3课: 数据库
- laravel教程第4课: Facade
- laravel教程第5课: 路由
- laravel教程第6课: 服务提供商
- laravel教程第7课: 全局中间件和路由中间件
- laravel教程第8课: 事件
- laravel教程第9课: 缓存
- laravel教程第10课: Session
- laravel教程第11课: Request
- laravel教程第12课: Response
- laravel教程第13课: macroable
全局中间件和路由中间件
一:全局中间件
与全局中间件相关的属性(1个)和方法(3个)
围绕 kernel中的保护属性
$middleware
转
# /Illuminate/Foundation/Http/Kernel.php
protected $middleware = [];
格式是一个索引数组,值是中间件类名,是一个字符串
array:6 [
0 => "App\Http\Middleware\TrustProxies"
1 => "Illuminate\Http\Middleware\HandleCors"
2 => "App\Http\Middleware\PreventRequestsDuringMaintenance"
3 => "Illuminate\Foundation\Http\Middleware\ValidatePostSize"
4 => "App\Http\Middleware\TrimStrings"
5 => "Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull"
]
注册(配置)的方法
1️⃣ 在 app/Http/Kernel.php
中直接配置
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
2️⃣ 在服务提供商的register或boot方法中prepend
或push
$this->app[\Illuminate\Contracts\Http\Kernel::class]->pushMiddleware($middleware);
$this->app->make(HttpKernel::class)->pushMiddleware(ServeNova::class);
$kernel->prependMiddleware(HandleCors::class);
❓ 有其它的方法可以修改全局中间件吗?
/bootstrap/app.php
中,应用实例化之后立即注册Kernel服务
$app->singleton(Illuminate\Contracts\Http\Kernel::class,App\Http\Kernel::class);
所以在服务提供商中可以调用 App\Http\Kernel
中定义的方法。我的想法是在app/Http/Kernel.php
中定义读取全局中间件的方法,如
public function getMiddleware(){
return $this->middleware;
}
public function setMiddleware($middlewares){
return $this->middleware=$middlewares;
}
❓ 全局中间件的顺序怎么控制?
二:路由中间件
Kernel中路由中间件属性
在 /Illuminate/Foundation/Http/Kernel.php
中有3个相关属性,可以app/Http/Kernel.php
中直接配置
protected $middlewareGroups = [];
protected $routeMiddleware = []; // 与middlewareAliases一样,deprecated
protected $middlewareAliases = [];
protected $middlewarePriority = [
\Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
\Illuminate\Cookie\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::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\ThrottleRequestsWithRedis::class,
\Illuminate\Contracts\Session\Middleware\AuthenticatesSessions::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
格式如下:
#middlewareGroups: array:2 [▼
"web" => array:6 [▼
0 => "App\Http\Middleware\EncryptCookies"
1 => "Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse"
2 => "Illuminate\Session\Middleware\StartSession"
3 => "Illuminate\View\Middleware\ShareErrorsFromSession"
4 => "App\Http\Middleware\VerifyCsrfToken"
5 => "Illuminate\Routing\Middleware\SubstituteBindings"
]
"api" => array:2 [▼
0 => "Illuminate\Routing\Middleware\ThrottleRequests:api"
1 => "Illuminate\Routing\Middleware\SubstituteBindings"
]
]
#routeMiddleware: []
#middlewareAliases: array:11 [▼
"auth" => "App\Http\Middleware\Authenticate"
"auth.basic" => "Illuminate\Auth\Middleware\AuthenticateWithBasicAuth"
"auth.session" => "Illuminate\Session\Middleware\AuthenticateSession"
"cache.headers" => "Illuminate\Http\Middleware\SetCacheHeaders"
"can" => "Illuminate\Auth\Middleware\Authorize"
"guest" => "App\Http\Middleware\RedirectIfAuthenticated"
"password.confirm" => "Illuminate\Auth\Middleware\RequirePassword"
"precognitive" => "Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests"
"signed" => "App\Http\Middleware\ValidateSignature"
"throttle" => "Illuminate\Routing\Middleware\ThrottleRequests"
"verified" => "Illuminate\Auth\Middleware\EnsureEmailIsVerified"
]
#middlewarePriority: array:11 [▼
0 => "Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests"
1 => "Illuminate\Cookie\Middleware\EncryptCookies"
2 => "Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse"
3 => "Illuminate\Session\Middleware\StartSession"
4 => "Illuminate\View\Middleware\ShareErrorsFromSession"
5 => "Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests"
6 => "Illuminate\Routing\Middleware\ThrottleRequests"
7 => "Illuminate\Routing\Middleware\ThrottleRequestsWithRedis"
8 => "Illuminate\Contracts\Session\Middleware\AuthenticatesSessions"
9 => "Illuminate\Routing\Middleware\SubstituteBindings"
10 => "Illuminate\Auth\Middleware\Authorize"
]
Kernel中路由中间件方法(9个)
/Illuminate/Foundation/Http/Kernel.php
中定义了5个方法
protected function syncMiddlewareToRouter()
public function getMiddlewarePriority()
public function prependToMiddlewarePriority($middleware)
public function appendToMiddlewarePriority($middleware)
public function getMiddlewareGroups()
public function prependMiddlewareToGroup($group, $middleware)
public function appendMiddlewareToGroup($group, $middleware)
public function getRouteMiddleware() // deprecated
public function getMiddlewareAliases()
Router中路由中间件属性
protected $middleware = [];
protected $middlewareGroups = [];
public $middlewarePriority = [];
格式如下
middleware: array:11 [▼
"auth" => "App\Http\Middleware\Authenticate"
"auth.basic" => "Illuminate\Auth\Middleware\AuthenticateWithBasicAuth"
"auth.session" => "Illuminate\Session\Middleware\AuthenticateSession"
"cache.headers" => "Illuminate\Http\Middleware\SetCacheHeaders"
"can" => "Illuminate\Auth\Middleware\Authorize"
"guest" => "App\Http\Middleware\RedirectIfAuthenticated"
"password.confirm" => "Illuminate\Auth\Middleware\RequirePassword"
"precognitive" => "Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests"
"signed" => "App\Http\Middleware\ValidateSignature"
"throttle" => "Illuminate\Routing\Middleware\ThrottleRequests"
"verified" => "Illuminate\Auth\Middleware\EnsureEmailIsVerified"
]
middlewareGroups: array:2 [▼
"web" => array:6 [▼
0 => "App\Http\Middleware\EncryptCookies"
1 => "Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse"
2 => "Illuminate\Session\Middleware\StartSession"
3 => "Illuminate\View\Middleware\ShareErrorsFromSession"
4 => "App\Http\Middleware\VerifyCsrfToken"
5 => "Illuminate\Routing\Middleware\SubstituteBindings"
]
"api" => array:2 [▼
0 => "Illuminate\Routing\Middleware\ThrottleRequests:api"
1 => "Illuminate\Routing\Middleware\SubstituteBindings"
]
]
# 是public属性,可以直接修改
middlewarePriority: array:11 [▼
0 => "Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests"
1 => "Illuminate\Cookie\Middleware\EncryptCookies"
2 => "Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse"
3 => "Illuminate\Session\Middleware\StartSession"
4 => "Illuminate\View\Middleware\ShareErrorsFromSession"
5 => "Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests"
6 => "Illuminate\Routing\Middleware\ThrottleRequests"
7 => "Illuminate\Routing\Middleware\ThrottleRequestsWithRedis"
8 => "Illuminate\Contracts\Session\Middleware\AuthenticatesSessions"
9 => "Illuminate\Routing\Middleware\SubstituteBindings"
10 => "Illuminate\Auth\Middleware\Authorize"
]
Router中路由中间件方法(11个)
在 /Illuminate/Routing/Router.php
中定义了11个
public function gatherRouteMiddleware(Route $route){
return $this->resolveMiddleware($route->gatherMiddleware(), $route->excludedMiddleware());
}
public function resolveMiddleware(array $middleware, array $excluded = [])
protected function sortMiddleware(Collection $middlewares)
public function getMiddleware()
public function aliasMiddleware(别名, 类名)
public function hasMiddlewareGroup($name)
public function middlewareGroup(群名如web,nova, 中间件类名组成的数组)
# 向中间件组(如web,api,nova)中的最前面加一个中间件
public function prependMiddlewareToGroup($group, $middleware)
public function pushMiddlewareToGroup($group, $middleware)
public function removeMiddlewareFromGroup($group, $middleware)
public function flushMiddlewareGroups()
路由中间件注册(配置)的方法
全局中间件,只需要在app/Http/Kernel.php
中配置好就行,也可以在服务提供商中的register或boot方法中使用$kernel->prepend|pushMiddleware
在最前面或最后面添加中间件就可以了,但路由中间件的配置分两步
第一步:配置Router
1️⃣ 在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,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
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,
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
protected $middlewarePriority = [
\Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
\Illuminate\Cookie\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::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\ThrottleRequestsWithRedis::class,
\Illuminate\Contracts\Session\Middleware\AuthenticatesSessions::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
2️⃣ 在服务提供商中配置
第二步:路由器中注册的中间件指定给各个路由
在路由文件routes.php中直接指定
// 多个中间件共用相同的中间件,如注册和登录两个使用guest中间件
Route::middleware('guest')->group(function () {
Route::get('login', Login::class)
->name('login');
Route::get('register', Register::class)
->name('register');
});
Route::middleware([
'web',
InitializeTenancyByDomain::class,
PreventAccessFromCentralDomains::class,
])->group(function () {
Route::get('/', function () {
return 'This is your multi-tenant application. The id of the current tenant is ' . tenant('id');
});
});
3️⃣4️⃣