ベーシック認証にフォーム入力を使う(mod_auth_form)
これは何?
パスワード制限付きのページを作りたいときに手軽に使えるベーシック認証ですが、パスワードの入力画面がポップアップしてくる仕様は入力しづらく、クライアントからもあまり好まれません。
そこで mod_auth_form を使い、フォーム入力でベーシック認証が使えるように設定した際のメモです。
動作検証環境
- CentOS Stream release 8
- Apache/2.4.37 (centos)
構成
ホームディレクトリ:/var/www
/html
├ .htaccess
├ auth-login.html
├ logout.html
└ /auth #この配下はパスワード制限付きとする
├ .htaccess
└ index.html
/var
└ .htpasswd
実装
/authディレクトリにベーシック認証をかける
/authディレクトリに.htaccess、任意の場所に.htpasswdを設置し、ベーシック認証をかけます。
mod_auth_formにする前に、ここで問題なく動作するか確認しておきます。
require valid-user
AuthUserfile "/var/www/var/.htpasswd"
AuthGroupfile /dev/null
AuthName "realm"
AuthType Basic
ログイン用のフォームを作成する
/authディレクトリ以外の場所に、ログイン用のフォームを作成します。
フォームのaction先として、存在しないファイルを指定します。ここでは「dologin.html」としました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex, nofollow">
<title>ログイン</title>
</head>
<body class="login">
<form method="POST" action="dologin.html" class="loginform">
<p>ユーザー名:
<input type="text" name="httpd_username" value="">
</p>
<p>パスワード:
<input type="password" name="httpd_password" value="">
</p>
<p>
<button type="submit" name="login" value="Login">ログイン</button>
</p>
</form>
</body>
</html>
ログイン後のページを作成する
/authディレクトリの中に、ログイン後のページを作成します。
ここに、ログアウト用のボタンも作成します。リンク先として、存在しないファイルを指定します。ここでは「dologout.html」としました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex, nofollow">
<title>会員向けのページ</title>
</head>
<body class="authpage">
<p>ここに認証後に表示するコンテンツが入ります。</p>
<p>[<a href="../dologout.html">ログアウト</a>]</p>
</body>
</html>
ログアウト時の画面を作成する
ログアウトボタンを押した後に表示されるページ(ログアウトしました等)を作成します。
ローディングのくるくる回る画像を表示させるだけにして、数秒後にmeta refreshでログイン画面に飛ばすという処理をさせてもいいかと思います。お好みで。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex, nofollow">
<title>ログアウト</title>
</head>
<body>
<p>ログアウトしました。</p>
<p>[<a href="auth-login.html">ログイン画面に戻る</a>]</p>
</body>
</html>
.htaccessにmod_auth_formの設定をする
ログインフォームを設置した階層に新たに.htaccessを作成し、mod_auth_formの設定をします。また、/auth配下に置いた.htaccessも合わせて修正します。
#ログイン時の処理
<Files "dologin.html"> #ログインフォームのアクション先として指定したファイル名
SetHandler form-login-handler
AuthFormLoginRequiredLocation /auth-login.html #ログインフォームのページ
AuthFormLoginSuccessLocation /auth/index.html #ログイン後のページ
AuthFormProvider file
AuthUserFile "/var/www/var/.htpasswd" #ベーシック認証の.htpasswdファイル
AuthType form
AuthName "realm"
Session On
SessionMaxAge 0 #セッションの有効期限。0で無期限。秒単位で定義。
SessionCookieName session path=/
SessionCryptoPassphrase hogehogefugafuga
</Files>
#ログアウト時の処理
<Files "dologout.html"> #ログアウトのリンク先として指定したファイル名
SetHandler form-logout-handler
AuthFormLogoutLocation "/logout.html" #ログアウト後のページ
Session On
SessionMaxAge 1 #1秒に設定することでセッションを強制的に切る。(0だと無期限になってしまうため)
SessionCookieName session path=/
SessionCryptoPassphrase hogehogefugafuga
</Files>
#ログアウト後に表示するページ用の処理(ログインしていないと表示できないように)
<Files "logout.html">
require valid-user
AuthFormProvider file
AuthUserFile "/var/www/var/.htpasswd"
AuthType form
AuthName "realm"
AuthFormLoginRequiredLocation /auth-login.html #ログインしていない場合に表示するページ
Session On
SessionCookieName session path=/
SessionCryptoPassphrase hogehogefugafuga
</Files>
require valid-user
AuthUserfile "/var/www/var/.htpasswd"
AuthGroupfile /dev/null
AuthName "realm"
- AuthType Basic
+ AuthType form
+ AuthFormProvider file
+ AuthFormLoginRequiredLocation /auth-login.html
+ Session On
+ SessionCookieName session path=/
+ SessionCryptoPassphrase hogehogefugafuga
注意事項
ベーシック認証は、常にパスワードをつけて通信している状態なので、SSLが使えないサイトはNGです。.htaccessにも、mod_rewriteで強制的にSSL通信するように書いておいたほうがいいです。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</IfModule>
公式サイトより
フォーム認証はmod_session モジュールに依存し、これらのモジュールはHTTP Cookieを利用するため、クロスサイトスクリプティング攻撃の犠牲になったり、潜在的に個人情報をクライアントに公開したりする可能性があります。サーバーでセッション機能を有効にする前に、関連するリスクが考慮されていることを確認してください。
Discussion