Apache + PHP + PostgreSQL で認証ページを作る (2)

(2) PostgreSQL でのデータベースの準備

認証情報は PostgreSQL 上にデータベースを作るわけですが、そのインタフェースの説明は、ドキュメント(mod_auth_pgsql.html)の冒頭のわずかこれだけです。


    *  Authentication

	One database, and one (or two) tables.  One table holds the username and the encryped (or plain) password.
 	The other table holds the username and the names of the group to which the user belongs.  
	It is possible to have username, groupname and password in the same table. 

    * Access Logging

	Every authentication access is logged in the same database of the authentication table, but in different table.
	User name and date of the request are logged.
	As option, it can log password, ip address, request line.
英語が読めない人であってもほんのちょびっとの説明しかないことは分かるでしょうが、超(いいかげん)訳してみると。


    *  認証DB

	このデータベースは1つ(または2つ)のテーブルを含みます。(訳注:2つにする場合)片方には
	username と 平文またはハッシュ化されたパスワード情報を格納します。もう1つには username と
	所属するグループを格納します。username, グループ, パスワードは1つのテーブルにあってもかま
	いません。

    * アクセスログDB

	認証DBへのアクセスは別のテーブルに記録されます。基本的には username と日時が記録されます
	オプションとして、パスワードやIPアドレス、リクエスト行を記録することもできます。

具体的にどのデータベースのどのテーブルにどうやって接続するかは .htaccess などへディレクティブとして記述するようにできているみたいです。

実際にデータベースを作る前に .htaccess を書くとだれもアクセスできなくなってしまうので、先にデータベースを作ることにしましょう。

まず、web アクセス用ユーザを作成します。


%createuser www
Shall the new user be allowed to create databases? (y/n) n
Shall the new user be allowed to create more new users? (y/n) n
CREATE USER
                                                                                

では、実際にデータベースを作成してみましょう。今回の設計は以下のようにしてみました。忘れずに www ユーザからアクセスできるよう権限を与えます。Web上からのパスワード変更を予定しているので書き込み権限も必要です。


%createdb mod_auth_pgsql
CREATE DATABASE
%psql mod_auth_pgsql
Welcome to psql 7.4.6, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

mod_auth_pgsql=# create table users (
mod_auth_pgsql(# name varchar (32) primary key,
mod_auth_pgsql(# uid integer,
mod_auth_pgsql(# pass varchar (32),
mod_auth_pgsql(# flag integer,
mod_auth_pgsql(# rsv1 varchar (40)
mod_auth_pgsql(# );
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "users_pkey" for
table "users"
CREATE TABLE
mod_auth_pgsql=# grant all on users to www;
GRANT
mod_auth_pgsql=# \q

表にするとこうなります。

列名データ型データ長備考
name可変長文字列型32ユーザ名(主キー)
uid整数型-ユーザID番号(予備)
pass可変長文字列型32パスワード格納フィールド
flag整数型-ユーザの属性を示すフラグ類
rsv1可変長文字列型40予約領域

認証を利用するWebアプリケーションが複数ある場合にそなえて、利用可能なアプリケーションやIDの有効期限などは必要であれば別テーブルを作成するようにしたいと思います。また、複数のWebアプリケーション間でユーザ名が重複する可能性のある場合には、name と uid での複合キーにするという方法もあります。

ではさっそくデータを1件いれてみます。


%psql mod_auth_pgsql
Welcome to psql 7.4.6, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

mod_auth_pgsql=# insert into users values('admin',0,'admin2004',1,'');
INSERT 17147 1
mod_auth_pgsql=# \q
                                                                                

いうまでもないが、パスワードを変更する場合には、以下のような SQL 文でなおせます。


mod_auth_pgsql=# update users set pass = 'admin2004' where name = 'admin';
                                                                                

見れば分かるとおり、今はパスワードは平文で admin2004 にしています。。

では、実際にアクセス制御をかける実験をしてみましょう。

適当なディレクトリに .htaccess を置きます。ここに記述するディレクティブはドキュメントに書かれています。またサンプルも掲載されています。せっかくなのでサンプルを利用することにします。


AuthName "My PostgreSQL Authenticator"
AuthType basic

Auth_PG_host localhost
Auth_PG_port 5432
Auth_PG_user pgsql
Auth_PG_database mod_auth_pgsql
Auth_PG_pwd_table users
Auth_PG_uid_field name
Auth_PG_pwd_field pass
Auth_PG_encrypted off

<LIMIT GET POST>
require valid-user
</LIMIT>
                                                                                

うまく動かない場合は、apache の error ログにいろんな情報が出力されます。何かの参考になればと思い、私の恥をさらしておきます。


[Wed Dec 22 14:16:20 2004] [alert] [client 192.168.5.1] /usr/local/apache/htdocs
/manual/.htaccess: Invalid command 'Auth_PG_ebcrypted', perhaps mis-spelled or d
efined by a module not included in the server configuration

 …なんかミスタイプしてるんちゃうの。…ってたしかに間違ってました。

[Wed Dec 22 14:23:41 2004] [error] (43)Protocol not supported: access to /usr/lo
cal/apache/htdocs/manual/mod/core.html failed for 192.168.5.1, reason: PGSQL 3:
ERROR:  column "password" does not exist\n -- Query: select password from users
where user='admin'

 …パスワードを格納するフィールド名は "password" じゃなくて "pass" でしょ。

[Wed Dec 22 16:23:45 2004] [error] (43)Protocol not supported: access to /usr/lo
cal/apache/htdocs/manual/mod/core.html failed for 192.168.5.1, reason: mod_auth_
pgsql: Password for user www not found (PG-Authoritative)

…最後まで悩んだ問題。ユーザ名を入れるフィールドは user ではなく name でしたね。
 自分で名前を付けておいてこの始末。やはり直感的に分かるフィールド名が一番。
                                                                                

もう1点気を付けないといけないのが、デフォルトの httpd.conf の設定です。

ソースからコンパイルした直後の /usr/local/apache/conf/httpd.conf では、.htaccess を読み込んでくれない設定になっています。


<Directory "/usr/local/apache/htdocs">

#
# This may also be "None", "All", or any combination of "Indexes",
# "Includes", "FollowSymLinks", "ExecCGI", or "MultiViews".
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
    Options Indexes FollowSymLinks MultiViews
    AllowOverride AuthConfig

#
# This controls which options the .htaccess files in directories can
# override. Can also be "All", or any combination of "Options", "FileInfo",
# "AuthConfig", and "Limit"
#
    AllowOverride None

この設定ではコメントにあるとおり、.htaccess を読んでくれません。どの程度まで Allow するかはポリシーによりますが、これが原因かどうか切り分けるためには AllowOverride All とすればとりあえずは通ります。

次回はセッションを使ったもうちょっとアプリケーション的な作りこみをしてみる予定です。

次へ

前へ