Buno Journals

It's what I do that defines me.

PHPでBasic認証サンプル

Web開発に携わっていれば、Basic認証に触れる機会は必ずある。今回、基本的な仕組みを整理してみた。

Basic認証

サーバがクライアント(ブラウザ)にBasic認証を要求する場合、

のレスポンスを返す。

それを受けて、ブラウザは、Base64エンコードされたユーザ名とパスワードを、Authorizationヘッダに付与してリクエストを送る。

Authorization: Basic ('ユーザ名:パスワード'をBase64でエンコード)

PHPの実装サンプル

以下は、phpでの簡単なBasic認証の実装例だ。 あくまで動作確認のため、ユーザ名、パスワードに何かしら入力があれば認証を通す、という簡単なものだ。 なお今回、phpを動かすwebサーバ環境の構築については触れない。

basic_authentification_sample.php

<?php
  $user = @$_SERVER['PHP_AUTH_USER'];
  $pass = @$_SERVER['PHP_AUTH_PW'];

  if (! $user || ! $pass) {
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Basic realm="Basic Authentication Sample"');
    echo "ユーザ名とパスワードが必要です";
    exit;
  }
?>
<body>
認証しました<BR>
ユーザ名:<?php echo htmlspecialchars($user, ENT_NOQUOTES, 'UTF-8'); ?><BR>
パスワード:<?php echo htmlspecialchars($pass, ENT_NOQUOTES, 'UTF-8'); ?> <BR>
</body>

phpは、authorizationヘッダに付与されたユーザ名、パスワードにそれぞれ $_SERVER['PHP_AUTH_USER']$_SERVER['PHP_AUTH_PW']で取得している。

動作の流れ

まず、上記phpファイルにHTTP GETリクエストでアクセスする。 この時、リクエストヘッダにAuthorizationヘッダはないため、ステータスコード401 Unauthorizedが返ってくる。

401 Unauthorized

認証が必要である。Basic認証やDigest認証などを行うときに使用される。 たいていのブラウザはこのステータスを受け取ると、認証ダイアログを表示する。

HTTPステータスコード - Wikipedia

f:id:bunoacts:20160705182454p:plain

ブラウザが表示したダイアログにユーザ名、パスワードを入力して送信すると、ブラウザは再びGETリクエストを送信する。

この時はAuthorizationヘッダにBase64エンコードされたユーザ名、パスワードが付与されている。

f:id:bunoacts:20160705183003p:plain

前述のPHPのコードはサーバ変数でユーザ名、パスワードにアクセスしhtml上に表示する。

f:id:bunoacts:20160705183219p:plain

ステートレス

これ以降、同じURLにアクセスしても認証ダイアログは表示されないが、それはブラウザが記憶したauthorizationヘッダを毎回自動的に付与してリクエストを送っているからである。HTTPもBasic認証もステートレスで、ログインという状態が保存されている訳ではない。

参考

体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践

体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践

HTTP クライアントを作ってみよう(5) - Basic 認証編 -

PHP: $_SERVER - Manual