HTTP 中間件

2018-12-17 10:41 更新

簡(jiǎn)介

HTTP 中間件提供一個(gè)方便的機(jī)制來(lái)過(guò)濾進(jìn)入應(yīng)用程序的 HTTP 請(qǐng)求,例如,Laravel 默認(rèn)包含了一個(gè)中間件來(lái)檢驗(yàn)用戶身份驗(yàn)證,如果用戶沒(méi)有經(jīng)過(guò)身份驗(yàn)證,中間件會(huì)將用戶導(dǎo)向登錄頁(yè)面,然而,如果用戶通過(guò)身份驗(yàn)證,中間件將會(huì)允許這個(gè)請(qǐng)求進(jìn)一步繼續(xù)前進(jìn)。

當(dāng)然,除了身份驗(yàn)證之外,中間件也可以被用來(lái)執(zhí)行各式各樣的任務(wù),CORS 中間件負(fù)責(zé)替所有即將離開程序的響應(yīng)加入適當(dāng)?shù)捻憫?yīng)頭,一個(gè)日志中間件可以記錄所有傳入應(yīng)用程序的請(qǐng)求。 Laravel 框架已經(jīng)內(nèi)置一些中間件,包括維護(hù)、身份驗(yàn)證、CSRF 保護(hù),等等。所有的中間件都位于 app/Http/Middleware 目錄內(nèi)。

           

建立中間件

要建立一個(gè)新的中間件,可以使用 make:middleware 這個(gè) Artisan 命令:

php artisan make:middleware OldMiddleware

           

此命令將會(huì) 在 app/Http/Middleware 目錄內(nèi)置立一個(gè)名稱為 OldMiddleware 的類。在這個(gè)中間件內(nèi)我們只允許 年齡 大于 200 的才能訪問(wèn)路由,否則,我們會(huì)將用戶重新導(dǎo)向 「home」 的 URI 。

<?php namespace App\Http\Middleware;use Closure;class OldMiddleware {

    /**
     * Run the request filter.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->input('age') < 200)
        {
            return redirect('home');
        }

        return $next($request);
    }}

           

如你所見,若是 年齡 小于 200 ,中間件將會(huì)返回 HTTP 重定向給客戶端,否則,請(qǐng)求將會(huì)進(jìn)一步傳遞到應(yīng)用程序。只需調(diào)用帶有 $request$next 方法,即可將請(qǐng)求傳遞到更深層的應(yīng)用程序(允許跳過(guò)中間件) HTTP 請(qǐng)求在實(shí)際碰觸到應(yīng)用程序之前,最好是可以層層通過(guò)許多中間件,每一層都可以對(duì)請(qǐng)求進(jìn)行檢查,甚至是完全拒絕請(qǐng)求。

Before / After 中間件

在一個(gè)請(qǐng)求前后指定某個(gè)中間件取決于這個(gè)中間件自身。這個(gè)中間件可以執(zhí)行在請(qǐng)求前執(zhí)行一些 前置 操作:

<?php namespace App\Http\Middleware;use Closure;class BeforeMiddleware implements Middleware {

    public function handle($request, Closure $next)
    {
        // Perform action
        return $next($request);
    }}

           

然后,這個(gè)中間件也可以在請(qǐng)求后執(zhí)行一些 后置 操作:

<?php namespace App\Http\Middleware;use Closure;class AfterMiddleware implements Middleware {

    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // Perform action
        return $response;
    }}

           

           

注冊(cè)中間件

全局中間件

若是希望中間件被所有的 HTTP 請(qǐng)求給執(zhí)行,只要將中間件的類加入到 app/Http/Kernel.php$middleware 屬性清單列表中。

指派中間件給路由

如果你要指派中間件給特定的路由,你得先將中間件在 app/Http/Kernel.php 配置一個(gè)鍵值,默認(rèn)情況下,這個(gè)文件內(nèi)的 $routeMiddleware 屬性已包含了 Laravel 目前配置的中間件,你只需要在清單列表中加上一組自定義的鍵值即可。 中間件一旦在 HTTP kernel 文件內(nèi)被定義,你即可在路由選項(xiàng)內(nèi)使用 middleware 鍵值來(lái)指派:

Route::get('admin/profile', ['middleware' => 'auth', function(){
    //}]);

           

           

可終止中間件

有些時(shí)候中間件需要在 HTTP 響應(yīng)已被發(fā)送到用戶端之后才執(zhí)行,例如,Laravel 內(nèi)置的 「session」 中間件,保存 session 數(shù)據(jù)是在響應(yīng)已被發(fā)送到用戶端 之后 才執(zhí)行。為了做到這一點(diǎn),你需要定義中間件為「可終止的」。

use Closure;use Illuminate\Contracts\Routing\TerminableMiddleware;class StartSession implements TerminableMiddleware {

    public function handle($request, Closure $next)
    {
        return $next($request);
    }

    public function terminate($request, $response)
    {
        // Store the session data...    }}

           

如你所見,除了定義 handle 方法之外, TerminableMiddleware 定義一個(gè) terminate 方法。這個(gè)方法接收請(qǐng)求和響應(yīng)。一旦定義了 terminable 中間件,你需要將它增加到 HTTP kernel 文件的全局中間件清單列表中。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)