Laravelでデータベースを使わずBasic認証する方法

Laravelでデータベースを使わずBasic認証する方法

723 回閲覧されました

みなさんこんにちは、jonioです。

Laravelで特定のページだけユーザーネームとパスワードの認証に通ると見ることができるのを実装しようと思い探したら見つけることができました。

アウトプットの為この記事を残します。

また、欠点もあるのでそれについても解説します。

Laravelのバージョン

8です。

Basic認証というのを使いますがバージョン6から実装されたみたいです。

欠点

認証は一度通るとずっと通ったままになりもう一度認証をかけたい場合はユーザー名かパスワードを変更しないといけません。

ネットを調べまくったのですが認証が通ったままになるのはそういう仕様でどうしようもないみたいです。

またデータベースを使わないので人によってランダムなパスワードにするとかできません。

それでは実装方法のアウトプットをします。

ミドルウェアの作成

下記のコマンドを叩きます。

php artisan make:middleware BasicAuthMiddleware

「BasicAuthMiddleware」は任意です。

コマンドを叩くと「Laravelのプロジェクト > app > Http > Middleware > BasicAuthMiddleware.php」を確認できます。

BasicAuthMiddleware.phpを修正します。

BasicAuthMiddleware.phpの修正

最初は下記になっています。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class BasicAuthMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request):(\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        return $next($request);
    }
}

handleメソッドの中身を修正します。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class BasicAuthMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
    
    
      //ここから修正
        $username = $request->getUser();
        $password = $request->getPassword();

        if ($username == '1' && $password == 'b') {
            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')
        ]);
      //ここまで修正
      
      
    }
}

22行目で認証フォームに入力するユーザー名(下記赤枠)を取得して23行目で認証フォーム(下記青枠)に入力するパスワードを取得します。

25行目〜27行目のif文の条件は「ユーザーネームが「1」でパスワードが「b」なら」という意味で26行目は次の処理に進む(認証が完了する)という意味です。

25行目の「1」「b」は自分でして下さい。

29行目〜32行目は調べたけどよく分からなかったのですがBasic認証をするのに必要みたいです。

ミドルウェアをKernelに登録します。

ミドルウェアをKernelに登録

「Laravelのプロジェクト > app > Http > Kernel.php」の「$routeMiddleware」に追記します。

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array<int, class-string|string>
     */
    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,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array<string, array<int, class-string|string>>
     */
    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' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array<string, class-string|string>
     */
    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,
        'basicauth' => \App\Http\Middleware\BasicAuthMiddleware::class,     //この行を追加
    ];
}

66行目を追加しています。

次はBasic認証を適用するルート設定をweb.phpに追記します。

web.phpに追記

「Laravelのプロジェクト > routes > web.php」に追記します。

下記のコードの中にルート設定をします。

Route::group(['middleware' => 'basicauth'],function(){
    //ここにルート設定をする
});

1行目の「basicauth」はKernelに登録した名称です。

ルート設定をしてBasic認証を行うページにアクセスすると以下の表示になります。

ちなみに認証フォームでキャンセルを押すと以下の画面に切り替わります。

これで実装が完成です。