このすみ技術ろぐ

とあるWebエンジニアが、技術や趣味について書くブログです。

Slim4にベーシック認証を導入する

業務で簡易なウェブサイトをPHP8 + Slim4で実装したのですが、限定公開にする必要があったので、ベーシック認証を導入しました。

とくに詰まるところはなかったのですが、記録として残します。

tuupola/slim-basic-auth

Slim4にベーシック認証を追加できるライブラリを探していたのですが、スター数や情報量を加味してもっとも良かったのが、 tuupola/slim-basic-auth です。

github.com

インストール方法

composerでインストールします。

$ composer require tuupola/slim-basic-auth

使い方

アプリケーションにミドルウェアとして追加します。 主要オプションについては、コメントで説明書きを加えました。

<?php
$app = AppFactory::create();

$app->add(new Tuupola\Middleware\HttpBasicAuthentication([
    "path" => ["/"], // ベーシック認証の対象とするパス
    "ignore" => ["/health/check"], // ベーシック認証の対象外とするパス
    "secure" => true, // secure(https)であることを必須とする

    // insecureでも許容するホスト名(たとえば開発環境など)
    "relaxed" => [
        "dev.example.com",
        "localhost",
        // ロードバランサーなどでTLS/SSLを終端するユースケースでは、headersを追加する
        "headers"
    ],

    // ユーザー名 => パスワード
    "users" => [
        "root" => "t00r",
        "somebody" => "passw0rd"
    ]
]));

おまけ

OSSなのでGitHub上でソースコードを眺めているのですが、行数も多くなく、コードリーディングに良さそうな実装規模です。

たとえばAuthorizationヘッダーから、base64_decode経由でユーザー名とパスワードを取得する処理の実装がわかります。

<?php
// https://github.com/tuupola/slim-basic-auth/blob/3.x/src/HttpBasicAuthentication.php
if (preg_match("/Basic\s+(.*)$/i", $request->getHeaderLine("Authorization"), $matches)) {
    $explodedCredential = explode(":", base64_decode($matches[1]), 2);
    if (count($explodedCredential) == 2) {
        list($params["user"], $params["password"]) = $explodedCredential;
    }
}

また、401ステータスでWWW-Authenticateヘッダーを出力し、クライアントへ認証を要求する過程もわかります。

<?php
if (false === $this->options["authenticator"]($params)) {
    /* Set response headers before giving it to error callback */
    $response = (new ResponseFactory)
        ->createResponse(401)
        ->withHeader(
            "WWW-Authenticate",
            sprintf('Basic realm="%s"', $this->options["realm"])
        );

    return $this->processError($response, [
        "message" => "Authentication failed"
    ]);
}

github.com