iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

2

今天要介紹的是中介層.

建立中介層

我們可以使用php artisan make:middleware指令去建立我們的中介層,因為建立及編輯商品需要限制為登入使用者且為管理者才可以進行存取,所以可以建立一個AuthUserAdminMiddleware的中介層檔案,幫我們做這個存取權限控制,建立完中介層檔案後,會在app/Http/Middleware/AuthUserAdminMiddleware.php路徑中看到這個檔案

php artisan make:middleware AuthUserAdminMiddleware
https://ithelp.ithome.com.tw/upload/images/20191015/20105694xjzihbzCav.png

結果
https://ithelp.ithome.com.tw/upload/images/20191015/20105694u7qtIeBFAx.png

中介層檔案框架會長得像下面範例,所有的請求都會經過handle()函式去處理,請求的資料$request會傳入到第一個變數,而下一個處理請求的函式則會放在第二個變數$next

所以在函式中間,我們可以對請求資料做處理或判斷,當有問題發生,像是權限不足時,則會做例外的處理。當處理完沒問題後,會再將目前的請求$request,丟給下一個處理請求的函式做處理$next($request),下一個處理請求的函式,可能是下一個中介層或控制器。

app/Http/Middleware/AuthUserAdminMiddleware.php

<?php

namespace App\Http\Middleware;

use Closure;

class AuthUserAdminMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
}

為了要限制管理者才能夠存取商品資料新增商品管理清單檢視商品單品編輯頁面檢視頁面商品單品資料修改這四個路由,我們的中介層判斷會長得像下面這樣

app/Http/Middleware/AuthUserAdminMiddleware.php

<?php

namespace App\Http\Middleware;

use App\Shop\Entity\User;
use Closure;

class AuthUserAdminMiddleware
{
    //處理請求
    public function handle($request, Closure $next)
    {
        //預設不允許存取
        $is_allow_access = false;
        //取得會員編號
        $user_id = session()->get('user_id');

        if(!is_null($user_id))
        {
            //Session有會員編號,取得會員資料
            $User = User::findOrFail($user_id);

            if($User->type == 'A')
            {
                //是管理者,允許存取
                $is_allow_access = true;
            }
        }

        if(!$is_allow_access)
        {
            //若不允許存取,重新導向至首頁
            return redirect()->to('/');
        }

        //允許存取,繼續做下個請求的處理
        return $next($request);
    }
}

一開始預設請求是不允許存取資料的,之後我們會從Session中取得會員編號,透過會員編號使用User Eloquent Model撈取使用者的資料,再判斷使用者是否為管理者帳號,若為管理者帳號,將此請求設定為允許存取資料的請求。

當最後資料處理結果,判斷這個請求是不允許存取資料的狀況時(非管理者登入),則會將這個請求重新導向至首頁,中斷後面所有的資料處理。當是管理者登入時,會設定此請求設定為允許存取資料的請求,所以會繼續將請求丟給下一個處理請求的函式,可能是下一個中介層或是控制器。

註冊中介層

當我們處理完中介層邏輯後,必須要註冊此中介層才可以開始使用這個中介層,註冊中介層的檔案放在app/Http/Kernel.php中,在類別檔案中可以看到有三個變數,分別是$middleware、$middlewareGroups及$routeMiddleware。

b. $middleware表示是整個Laravel應用程式共用的中介層,所有的請求都會經過這些中介層的處理。$middlewareGroups為路由中介層群組,所有的Web路由請求都會經過web的中介層群組處理,所有的API路由請求都會經過api的中介層群組處理。$routeMiddleware為個別的中介層,分別指定不同的名稱給中介層類別

app\Http\Kernel.php

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    //應用程式共用中介層
    protected $middleware = [
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\TrustProxies::class,
    ];

    //路由中介層群組
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

    //應用程式中介層
    protected $routeMiddleware = [
        'user.auth.admin' => \App\Http\Middleware\AuthUserAdminMiddleware::class,
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];
}

剛剛建立的登入使用者且為管理者才可以存取的中介層,為特定的路由請求,才需要做控制判斷權限的中介層,所以可以將此中介層寫在$routeMiddleware變數中,並指定此中介層名稱為user.auth.admin,這樣就可以完成中介層的註冊設定。

在路由使用中介層

在註冊設定完中介層後,可以在路由檔案中routes/web.php,指定商品資料新增、商品管理清單檢視、商品單品編輯頁面及商品單品資料修改這四個路由需要經過user.auth.admin中介層

routes/web.php

路由的設定可以透過個別指定中介層或路由群阻指定中介層的方式去指定,而指定的中介層資料為陣列資料,表示當我們有多個中介層需要設定時,可以在陣列傳入多個中介層名稱去進行設定。

//個別指定中介層
Route::get()->middleware(['user.auth.admin']);
//路由群組指定中介層
Route::group(['middleware'=>['user.auth.admin']], function(){
});

可以使用php artisan route::list指令去列出現在所有的路由,在這個路由清單中,最後面可以看到使用的中介層有哪些,你會看到Web路由請求都會經過web的中介層群組處理,而我們的商品資料新增商品管理清單檢視商品單品編輯頁面檢視頁面商品單品資料修改這四個路由也正確的加上user.auth.admin中介層了!

php artisan route:list
https://ithelp.ithome.com.tw/upload/images/20191015/20105694I6p1bcjZ1b.png

如果沒有建立TransactionController.php會報錯, 只要加上就可以了.


上一篇
[Day 35] Laravel實作 - 商品管理與瀏覽(二)
下一篇
[Day 37] Laravel實作 - 商品管理與瀏覽(四)
系列文
Laravel從入門到放棄…………原生PHP (疑?48

尚未有邦友留言

立即登入留言