久久精品水蜜桃av综合天堂,久久精品丝袜高跟鞋,精品国产肉丝袜久久,国产一区二区三区色噜噜,黑人video粗暴亚裔

Laravel中間件

2025-03-10 61

中間件為檢查和過濾進(jìn)入應(yīng)用程序的 HTTP 請求提供了一種方便的機(jī)制。比如 Laravel 提供了一個(gè)中間件,用于驗(yàn)證用戶是否通過身份驗(yàn)證,如果身份驗(yàn)證失敗,中間件則會(huì)將重定向到登錄頁,反之中間件將允許請求繼續(xù)進(jìn)入后面的業(yè)務(wù)邏輯。

除了身份驗(yàn)證,中間件還可以用于各種業(yè)務(wù)場景。比如,日志記錄中間件可以記錄所有傳入應(yīng)用程序的請求。 Laravel 自身也包含多種中間件,其中包括用于 身份驗(yàn)證 和 CSRF 保護(hù)的中間件;通常用戶定義的中間件都位于應(yīng)用程序的 app/Http/Middleware 目錄中。

一、定義Laravel中間件

可以使用 make:middleware Artisan 命令,來創(chuàng)建一條中間件:

php artisan make:middleware EnsureTokenIsValid

該命令將在 app/Http/Middleware 目錄中放置一個(gè)新的 EnsureTokenIsValid 類。在此中間件中,如果提供的 token 輸入與指定值匹配,將僅允許訪問路由。否則會(huì)將用戶重定向回 home URI:

<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureTokenIsValid
{
/**
* 處理傳入請求
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->input('token') !== 'my-secret-token') {
return redirect('home');
}

return $next($request);
}
}

上面代碼,如果給定的 token 與我們的密鑰不匹配,中間件將向客戶端返回 HTTP 重定向;否則,請求將進(jìn)一步傳遞到應(yīng)用程序中。要將請求更深入地傳遞到應(yīng)用程序(進(jìn)一步傳遞),應(yīng)該使用 $request 調(diào)用 $next 回調(diào)。

最好將中間件設(shè)想為一系列「層」,HTTP 請求在到達(dá)應(yīng)用程序之前必須經(jīng)過的部分,每一層都可以檢查請求,也可以完全拒絕它。

[! 注意]所有中間件都通過服務(wù)容器解析,因此您可以在中間件的構(gòu)造函數(shù)中鍵入提示所需的任何依賴項(xiàng)。

中間件響應(yīng)

中間件可以選擇在請求 之前 或 之后 執(zhí)行任務(wù)。

在應(yīng)用程序 處理請求之前 執(zhí)行任務(wù):

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class BeforeMiddleware
{
public function handle(Request $request, Closure $next): Response
{
// Perform action

return $next($request);
}
}

在應(yīng)用程序 處理請求之后 執(zhí)行任務(wù):

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class AfterMiddleware
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);

// Perform action

return $response;
}
}

二、注冊Laravel中間件

1、全局中間件

如果希望中間件在應(yīng)用程序的每個(gè) HTTP 請求期間運(yùn)行,可以將其附加到應(yīng)用程序的 bootstrap/app.php 文件中的全局中間件堆棧中:

use App\Http\Middleware\EnsureTokenIsValid;

->withMiddleware(function (Middleware $middleware) {
$middleware->append(EnsureTokenIsValid::class);
})

提供給 withMiddleware 閉包的 $middleware 對象是 Illuminate\Foundation\Configuration\Middleware 的實(shí)例,負(fù)責(zé)管理分配給應(yīng)用程序路由的中間件。 append 方法將中間件添加到全局中間件列表的末尾。如果想將中間件添加到列表的開頭,則應(yīng)使用 prepend 方法。

2、手動(dòng)管理全局中間件

如果想手動(dòng)管理 Laravel 的全局中間件堆棧,可以向 use 方法提供 Laravel 的默認(rèn)全局中間件堆棧。然后,可以根據(jù)需要調(diào)整默認(rèn)的中間件堆棧:

->withMiddleware(function (Middleware $middleware) {
$middleware->use([
// \Illuminate\Http\Middleware\TrustHosts::class,
\Illuminate\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Http\Middleware\ValidatePostSize::class,
\Illuminate\Foundation\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
]);
})

3、路由綁定

如果想將中間件分配給特定的路由,可以在定義路由時(shí)調(diào)用 middleware 方法:

use App\Http\Middleware\EnsureTokenIsValid;

Route::get('/profile', function () {
// ...
})->middleware(EnsureTokenIsValid::class);

可以通過將中間件名稱數(shù)組傳遞給 middleware 方法來將多個(gè)中間件分配給路由:

Route::get('/', function () {
// ...
})->middleware([First::class, Second::class]);

4、禁用中間件

將中間件分配給一組路由時(shí),有時(shí)可能需要阻止中間件應(yīng)用于組內(nèi)的單個(gè)路由,可以使用 withoutMiddleware 方法來完成此操作:

use App\Http\Middleware\EnsureTokenIsValid;

Route::middleware([EnsureTokenIsValid::class])->group(function () {
Route::get('/', function () {
// ...
});

Route::get('/profile', function () {
// ...
})->withoutMiddleware([EnsureTokenIsValid::class]);
});

還可以從 路由組 中禁用給定的中間件:

use App\Http\Middleware\EnsureTokenIsValid;

Route::withoutMiddleware([EnsureTokenIsValid::class])->group(function () {
Route::get('/profile', function () {
// ...
});
});

withoutMiddleware 方法只能移除路由中間件,不適用于全局中間件.

5、中間件分組

有時(shí)可能希望將多個(gè)中間件分組在一個(gè)鍵下,以便更輕松地將它們分配給路由。可以使用應(yīng)用程序的 bootstrap/app.php 文件中的 appendToGroup 方法來完成此操作:

use App\Http\Middleware\First;
use App\Http\Middleware\Second;

->withMiddleware(function (Middleware $middleware) {
$middleware->appendToGroup('group-name', [
First::class,
Second::class,
]);

$middleware->prependToGroup('group-name', [
First::class,
Second::class,
]);
})

中間件組可以使用與單個(gè)中間件相同的語法分配給路由和控制器操作:

Route::get('/', function () {
// ...
})->middleware('group-name');

Route::middleware(['group-name'])->group(function () {
// ...
});

6、Laravel 默認(rèn)中間件組

Laravel 包含預(yù)定義的 web 和 api 中間件組,其中包含可能想要應(yīng)用于 Web 和 API 路由的常見中間件。請記住,Laravel 會(huì)自動(dòng)將這些中間件組應(yīng)用到相應(yīng)的 routes/web.php 和 routes/api.php 文件:

(1)web 中間件組

Illuminate\Cookie\Middleware\EncryptCookies

Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse

Illuminate\Session\Middleware\StartSession

Illuminate\View\Middleware\ShareErrorsFromSession

Illuminate\Foundation\Http\Middleware\ValidateCsrfToken

Illuminate\Routing\Middleware\SubstituteBindings

(2)api 中間件組

Illuminate\Routing\Middleware\SubstituteBindings

如果想將中間件附加或添加到這些組中,則可以在應(yīng)用程序的 bootstrap/app.php 文件中使用 web 和 api 方法。 web 和 api 方法是 appendToGroup 方法的便捷替代方法:

use App\Http\Middleware\EnsureTokenIsValid;
use App\Http\Middleware\EnsureUserIsSubscribed;

->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
EnsureUserIsSubscribed::class,
]);

$middleware->api(prepend: [
EnsureTokenIsValid::class,
]);
})

甚至可以將 Laravel 的默認(rèn)中間件組條目之一替換為自己的自定義中間件:

use App\Http\Middleware\StartCustomSession;
use Illuminate\Session\Middleware\StartSession;

$middleware->web(replace: [
StartSession::class => StartCustomSession::class,
]);

也可以完全刪除中間件:

$middleware->web(remove: [
StartSession::class,
]);

7、手動(dòng)管理 Laravel 默認(rèn)中間件組

如果想手動(dòng)管理 Laravel 默認(rèn) web 和 api 中間件組中的所有中間件,可以完全重新定義這些組。下面的示例將定義 web 和 api 中間件組及其默認(rèn)中間件,允許根據(jù)需要自定義它們:

->withMiddleware(function (Middleware $middleware) {
$middleware->group('web', [
\Illuminate\Cookie\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
]);

$middleware->group('api', [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
// 'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
]);
})

[! 注意]默認(rèn)情況下 web 和 api 中間件組會(huì)通過 bootstrap/app.php 和 routes/api.php 文件。

8、中間件別名

可以在應(yīng)用程序的 bootstrap/app.php 文件中為中間件分配別名。中間件別名允許為給定的中間件類定義一個(gè)短別名,這對于具有長類名的中間件特別有用:

use App\Http\Middleware\EnsureUserIsSubscribed;

->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'subscribed' => EnsureUserIsSubscribed::class
]);
})

一旦在應(yīng)用程序的 bootstrap/app.php 文件中定義了中間件別名,就可以在將中間件分配給路由時(shí)使用該別名:

Route::get('/profile', function () {
// ...
})->middleware('subscribed');

為了方便起見,Laravel 的一些內(nèi)置中間件默認(rèn)是別名的。例如, auth 中間件是 Illuminate\Auth\Middleware\Authenticate 中間件的別名。以下是默認(rèn)中間件別名的列表:

別名 中間件
auth Illuminate\Auth\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 Illuminate\Auth\Middleware\RedirectIfAuthenticated
password.confirm Illuminate\Auth\Middleware\RequirePassword
precognitive Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests
signed Illuminate\Routing\Middleware\ValidateSignature
subscribed \Spark\Http\Middleware\VerifyBillableIsSubscribed
throttle Illuminate\Routing\Middleware\ThrottleRequests or Illuminate\Routing\Middleware\ThrottleRequestsWithRedis
verified Illuminate\Auth\Middleware\EnsureEmailIsVerified

9、中間件排序

極少數(shù)情況下,可能需要中間件按特定順序執(zhí)行,但在將它們分配給路由時(shí)無法控制它們的順序。在這些情況下,可以使用應(yīng)用程序的 bootstrap/app.php 文件中的 priority 方法指定中間件優(yōu)先級(jí):

->withMiddleware(function (Middleware $middleware) {
$middleware->priority([
\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\Foundation\Http\Middleware\ValidateCsrfToken::class,
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
\Illuminate\Auth\Middleware\Authorize::class,
]);
})

三、Laravel中間件參數(shù)

中間件還可以接收附加參數(shù)。例如,如果應(yīng)用程序需要在執(zhí)行給定操作之前驗(yàn)證經(jīng)過身份驗(yàn)證的用戶是否具有給定的 “角色”,可以創(chuàng)建一個(gè) EnsureUserHasRole 中間件來接收角色名稱作為附加參數(shù)。

其他中間件參數(shù)將在 $next 參數(shù)之后傳遞給中間件:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureUserHasRole
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next, string $role): Response
{
if (! $request->user()->hasRole($role)) {
// Redirect...
}

return $next($request);
}

}

定義路由時(shí)可以通過使用 : 分隔中間件名稱和參數(shù)來指定中間件參數(shù):

Route::put('/post/{id}', function (string $id) {
// ...
})->middleware('role:editor');

多個(gè)參數(shù)可以用逗號(hào)分隔:

Route::put('/post/{id}', function (string $id) {
// ...
})->middleware('role:editor,publisher');

四、可終止Laravel中間件

有時(shí),中間件可能需要在 HTTP 響應(yīng)發(fā)送到瀏覽器后執(zhí)行一些工作。如果在中間件上定義了 terminate 方法,并且 Web 服務(wù)器使用 FastCGI,則在響應(yīng)發(fā)送到瀏覽器后將自動(dòng)調(diào)用 terminate 方法:

<?php

namespace Illuminate\Session\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class TerminatingMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
return $next($request);
}

/**
* Handle tasks after the response has been sent to the browser.
*/
public function terminate(Request $request, Response $response): void
{
// ...
}
}

terminate 方法應(yīng)該接收請求和響應(yīng)。定義可終止中間件后,您應(yīng)該將其添加到應(yīng)用程序的 bootstrap/app.php 文件中的路由或全局中間件列表中。

當(dāng)在中間件上調(diào)用 terminate 方法時(shí),Laravel 將從服務(wù)容器中解析中間件的新實(shí)例。如果您想在調(diào)用 handle 和 terminate 方法時(shí)使用相同的中間件實(shí)例,請使用容器的 singleton 方法向容器注冊中間件。通常,這應(yīng)該在 AppServiceProvider 的 register 方法中完成:

use App\Http\Middleware\TerminatingMiddleware;

/**
* Register any application services.
*/
public function register(): void
{
$this->app->singleton(TerminatingMiddleware::class);
}

————————————————
原文作者:Laravel China 社區(qū)文檔:《Laravel 11 中文文檔(11.x)》
轉(zhuǎn)自鏈接:https://learnku.com/docs/laravel/11.x/middlewaremd/16658
版權(quán)聲明:翻譯文檔著作權(quán)歸譯者和 LearnKu 社區(qū)所有。轉(zhuǎn)載請保留原文鏈接

  • 廣告合作

  • QQ群號(hào):4114653

溫馨提示:
1、本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享網(wǎng)絡(luò)內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。郵箱:2942802716#qq.com(#改為@)。 2、本站原創(chuàng)內(nèi)容未經(jīng)允許不得轉(zhuǎn)裁,轉(zhuǎn)載請注明出處“站長百科”和原文地址。