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という名称で始まるパスはすでに稼働しているページだったので除外しました。
これで、通常のWebアクセスでは、除外以外のページ(/price~)はベーシック認証の対象になります。
このへんは各自必要に応じて変更してください。
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]
の中に放り込む方法だと、ベーシック認証を外したくなったらこの行を削除(またはコメントアウト)するだけで簡単に外せます。
無駄なコード汚染が減るのでありがたいですね。
この方法なら、静的サイトを作っていたころのように気軽にベーシック認証をかけることができそうです。
コメント