Help us understand the problem. What is going on with this article?

【Laravel】ルーティングのミドルウェアとは?作成手順と実例 (Route::midlewareの意味など)

ルーティングで使われるmidlewareとは何かについて。

▼こういうの

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
    //省略
});
Route::group(['middleware' => 'auth.very_basic'], function () {
    Route::get('/', function () {
    //省略
});


目次

  1. ミドルウェアとは?
  2. フローで見るMiddleware
  3. Middlewareを実際に使うまでの流れ
  4. ミドルウェアの作成(条件ファイルの作成)
  5. Middlewareの中身
  6. ミドルウェアの条件作成
  7. ミドルウェアの登録
  8. ミドルウェアをルートに適用


ミドルウェアとは?

HTTPリクエスト(またはレスポンス)をチェックする機能のこと。
middlewareは自分で関数を定義して作成できる。

▼用途

  • 指定した変数が条件を満たしているか
  • 認証ユーザーかどうか

など、、

フローで見るMiddleware

▼通常のフロー

通常のフロー
HTTP Request
 ↓
Route
 ↓
Controller
 ↓
View(Application)
 ↓
Response



▼ミドルウェアがある場合

ミドルウェアありのフロー
HTTP Request
 ↓
Route
 ↓
**Before Middleware**
 ↓
Controller
 ↓
View(Application)
 ↓
**After Middleware**
 ↓
Response

・Before Middleware:リクエストをチェックする機能
・Afrter Middleware:レスポンスをチェックする機能

ミドルウェアは複数設置可能。

image.png

参考:midium.com


Middlewareを実際に使うまでの流れ

Middlewareを実際に使用するまでには大きく3つのステップがある。

1. ミドルウェアの作成(条件ファイルの作成)
2. ミドルウェアの登録
3. ミドルウェアをルートに適用


ミドルウェアの作成(条件ファイルの作成)

artisanコマンドの、make:middlewareで生成できる。

php artisan make:middleware ミドルウェア名

$ php artisan make:middleware test

Middleware created successfully.

▼保存場所
app > HTTP > Middleware > ミドルウェア名.php

image.png

Middlewareの中身

作成したミドルウェアの中身は以下のようになっている。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

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

namespace App\Http\Middleware;
app > HTTP > Middlewareに保存されるので、名前空間も対応している。

use Closure;
Closureクラスをインポート。

▼Clouseクラスとは?
無名関数と呼ぶ。https://www.php.net/closure
ここでは、次の処理に進める変数$nextを使えるようにしている。

use Illuminate\Http\Request;
Laravelのコンポーネントである、Requestクラスをインポート。

説明文(PHPDocs)

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */

受け取ったrequestを処理する。

  • @param: パラメータの説明
    ここでは、$request$nextを使っていますという説明。参照元のクラスが示してある。

  • @return: 戻り値
    ここでは、戻り値の型はmixed(何でもとりうる)であることを示している。



・処理内容
functionにミドルウェアの処理を記述する。

public function handle(Request $request, Closure $next)
    {
        //処理
        return $next($request);
    }

return $next($request);
リクエストを次のステップに進めるという意味。

他にミドルウェアが設定されてない場合は、リクエストがコントローラーに渡される。


ミドルウェアの条件作成

実際にミドルウェアの条件部分を作ってみる。

Before Middlewareの作成

requestに対して実行するBefore Middlewareの実例。

class BeforeMiddleware
{
    public function handle($request, Closure $next)
    {
        if ($request->age >= 50) {
            return redirect('home');
        }

        return $next($request);
    }
}

requestで渡されたデータageの値が50を超えている場合は、ルート名homeにリダイレクトする。

50以下の場合は次の処理に進む。


After MiddleWare

responseに対して実行するAfter Middlewareの実例。

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

        if ($response->age >= 50) {
            return redirect('home');
        }

        return $response;
    }
}


Before MiddlewareとAfter Middlewareの違い

▼Before Middleware
- $requestに対して条件を指定
- return $next($request);を返す(通常の処理)



▼After Middleware
- $response = $next($request);に対して条件を指定
- return $response;を返す(通常の処理)


ミドルウェアの登録

ミドルウェアをルートに登録する方法は3つある。

  1. グローバル登録
  2. ルート登録
  3. グループ登録

ルート全体に通すか、個別にルートを指定するか、複数のミドルウェアをまとめて登録するかの違い。

いずれもApp\Http\Kernelクラスの中に記述する。(デフォルトでミドルウェアが登録されている。)

image.png

1. グローバル登録

すべてのルートにミドルウェアを適用するには、app/Http/Kernel.phpの$middlewareプロパティに追加する。

protected $middleware = [ ];

Kernel.php
protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Fruitcake\Cors\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. ルート登録

各ルートに個別にミドルウェアを適用するには、app/Http/Kernel.phpの$routeMiddlewareプロパティに追加する。

protected $routeMiddleware = [ 'ミドルウェア名' => 完全な名前空間::class];
Kernel.php
protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::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,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];


3. グループ登録

ミドルウェアをひとまとめにして適用するには、app/Http/Kernel.phpの$middlewareGroupsプロパティに追加する。

protected $middlewareGroups = [ 
   'グループミドルウェア名' => [
        完全な名前空間::class, 
        ,,,,
];

デフォルトでミドルウェア名webとapiが用意されている。(webはURIに、apiはAPIルートに適用する目的)

Kernel.php
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:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];


ミドルウェアをルートに適用

ルート登録したミドルウェア

$routeMiddlewareをルートに適用する方法。

->middleware('ミドルウェア名', 'ミドルウェア名',,,)



▼一つだけ適用する場合

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

URIにadmin/profileが入力された時、ミドルウェアauthを実行数する。



▼複数適用する場合

Route::get('/', function () {
    //
})->middleware('first', 'second');

ホームディレクトリにアクセスした場合に、ミドルウェアfirstとsecondを実行する。



▼名前空間で指定
ミドルウェア名ではなく、名前空間で指定もできる。

use App\Http\Middleware\CheckAge;

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


グループ登録したミドルウェア

ルート登録した場合と同じように名前で指定できる。

Route::get('/', function () {
    //
})->middleware('web');


グループ化したルートにミドルウェアを適用する

冒頭の
Route::middlewareや、
Route::group(['middleware' => 'auth.very_basic']
などの表記について。これらが何をやっているか。

Route::middleware

これまでの->middlewareを冒頭で呼び出している。後ろにグループ化したルートがくる場合に使われる。

Route::middleware('ミドルウェア名')->group()

後ろに続くグループ全体にミドルウェアを適用する。

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


Route::group(['middleware' => 'ミドルウェア名'], function(){ ルート });

groupメソッドの引数で適用するmiddlewareを指定している。

Route::group(['middleware' => 'auth.very_basic'], function () {
    Route::get('/', ['as' => 'top', 'uses' => 'TopController@index']);
    Route::get('privacy', 'PrivacyController@index')->name('privacy');
    Route::get('optout', 'OptoutController@index')->name('optout');
});

groupメソッドとは?


(補足)auth.very_basic

Laravel標準のauth.basicとは違い、実際のデータベースの情報を使うことなくBasic認証を追加するミドルウェア。

image.png
https://github.com/olssonm/l5-very-basic-auth/blob/master/README.jp.md

yuta-38
メモとして活用してます
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away