Laravelでベーシック認証×DB不使用×特定ページを除外……をとにかく簡単に実装する

Laravel
※当サイトはアフィリエイト広告を掲載しています。

Laravelで稼働中のサイトで、一部分リニューアルをする案件がありました。

その際、認証について考える機会がありました。要望としては以下の様なものです。

  • 稼働中のページはそのまま公開させたい
  • リニューアル部分は当然ユーザーに表示させたくない
  • でも顧客企業による表示確認は行いたい
  • わざわざDBのデータを使った認証は面倒臭い
  • ルート(web.php)をいじりたくない
  • 簡単に付けたい&外したい

DBのデータでベーシック認証させたことはありますが、今回はそういうのではありません。要は簡単にサクッと実装したいのです。しかも外すときも他に影響を与えずさっと外したい。

いうなれば静的サイトでベーシック認証するのと同じようなイメージです。

調べたところ、私の要望をちょうど満たすものは無かったので、自分なりに考えてみました。

結論

→Web全体にベーシック認証のミドルウェアをかませる。

ミドルウェア作成

まずはミドルウェアを作ります。

php artisan make:middleware BasicAuthMiddleware

以下の様に変更します。

<?php

namespace App\Http\Middleware;

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

class BasicAuthMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        // `/price` で始まるパスを基本認証から除外する
        if ($request->is('price*')) {
            return $next($request);
        }

        $username = $request->getUser();
        $password = $request->getPassword();

        if ($username == 'test' && $password == 'test') {
            return $next($request);
        }

        abort(401, "Enter username and password.", [
            header('WWW-Authenticate: Basic realm="Sample Private Page"'),
            header('Content-Type: text/plain; charset=utf-8')
        ]);
    }
}

21行目でユーザー名とパスワードを指定しています(この例ではともにtest)。

13行目~16行目で例外ページを指定しています。今回は、/priceという名称で始まるパスはすでに稼働しているページだったので除外しました。

今回は$request->is('price*')のようにURLパターンで判定しましたが、ルート名で$request->routeIs('price.*')のように判定する手もあります。

これで、通常のWebアクセスでは、除外以外のページ(/price~)はベーシック認証の対象になります。

Lara
Lara

このへんは各自必要に応じて変更してください。

Kernel.phpから読み込み

おなじみのApp\Http\Kernel.phpからミドルウェアを読み込みます。

ルートから指定するなら protected $middlewareAliases = []にエイリアスとともに足せば良いですが、今回はWebの通常リクエスト全てで適用したいです。

そのため$middlewareGroups['web]の中に放り込みました。

    // 略~
    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,
            // ↓↓↓↓↓↓↓ここに追加↓↓↓↓↓↓↓↓
            \App\Http\Middleware\BasicAuthMiddleware::class,  
        ],

        'api' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];
    // 略~

もちろん、エイリアスをつけてルートからミドルウェアを利用する方法も可能です。

ただ、$middlewareGroups['web]の中に放り込む方法だと、ベーシック認証を外したくなったらこの行を削除(またはコメントアウト)するだけで簡単に外せます。

無駄なコード汚染が減るのでありがたいですね。

この方法なら、静的サイトを作っていたころのように気軽にベーシック認証をかけることができそうです。

コメント

タイトルとURLをコピーしました