PHP による HTTP 認証

header 関数を使うと、 "Authentication Required" メッセージをクライアントブラウザに送ることができます。 これにより、クライアントブラウザではユーザー名とパスワードの入力要求 ウインドウがポップアップ表示されます。一度、ユーザーがユーザー名と パスワードを入力すると、PHP スクリプトを含むその URL は、次回以降、 定義済みの変数 PHP_AUTH_USER と、 PHP_AUTH_PW と、 AUTH_TYPE にそれぞれユーザー名、 パスワード、認証型が代入された状態で呼ばれます。 定義済みの変数は、配列 $_SERVER でアクセス可能です。 "Basic" 認証 のみ がサポートされています。詳細は、 headerを参照ください。

ページ上でクライアント認証を強制するスクリプトの例を以下に示します。

例1 Basic HTTP 認証の例

<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Basic realm="My Realm"');
    echo "ユーザーがキャンセルボタンを押した時に送信されるテキスト\n";
    exit;
} else {
    echo "<p>こんにちは、{$_SERVER['PHP_AUTH_USER']} さん。</p>";
    echo "<p>あなたは、{$_SERVER['PHP_AUTH_PW']} をパスワードとして入力しました。</p>";
}
?>

注意: 互換性

HTTPヘッダ行をコーディングする際には注意を要します。全てのクライアントへの 互換性を最大限に保証するために、キーワード "Basic" には、 大文字の"B"を使用して書くべきです。realm文字列は(一重引用符ではなく) 二重引用符で括る必要があります。また、HTTP/1.1 401 ヘッダ行のコード 401 の前には、 1つだけ空白を置く必要があります。 認証パラメータは、 カンマ区切りで指定しなければなりません。

単に PHP_AUTH_USERおよびPHP_AUTH_PW を出力するのではなく、ユーザー名とパスワードの有効性をチェックしたいと 思うかもしれません。 その場合、クエリーをデータベースに送るか、ある dbm ファイル中の ユーザーを調べるといったことをすることになるでしょう。

注意: Apache の設定

PHP は、外部認証が動作しているかどうかの判定を AuthType ディレクティブの有無で行います。

しかし、上記の機能も、認証を要求されないURLを管理する人が同じサーバー にある認証を要するURLからパスワードを盗むことを防ぐわけではありませ ん。

注意: ブラウザの挙動
HTTP Basic 認証は非常に基本的なもので、ログアウトをサポートするようには 設計されていません。HTTP はステートレスなプロトコルであるため、 ほとんどのブラウザは 2xx ステータスコードを受け取ると すぐに認証情報をキャッシュし、ブラウザを閉じるまですべてのリクエストで その認証情報を送信し続けます。サーバーが認証情報の再入力を求める プロンプトを要求するための標準的な方法は定義されていません。 長年にわたり、この問題に対するさまざまな回避策がインターネット上で 広まってきましたが、それらはすべて、異なるブラウザが未定義のエッジケース (あるいは HTTP 標準の違反さえも)をどのように処理するかに依存しています。 このような回避策は避け、Basic 認証を重要な用途に使用しないことが最善です。

注意: IIS の設定
IIS サーバーと CGI 版の PHP の組み合わせで HTTP 認証を使うには、 php.ini ディレクティブ cgi.rfc2616_headers0 (デフォルト値) に設定し、IIS の設定の "ディレクトリセキュリティ" を編集する必要があります。 "編集" ボタンを押して "匿名アクセス" のみをオンにしてください。 その他のフィールドはオフのままにしてください。