09 August 2008

PHP (PEAR Auth) でのユーザ認証

Basic認証を使う場合の例
※ ログアウト処理が不可能な事を実証するためのコード例


<html>
<body>
<?php

if (!isset($_SERVER['PHP_AUTH_USER'])) {
// 認証ダイアログを表示する
header("WWW-Authenticate: Basic realm=\"Basic Auth Test\"");
// 上記ダイアログでキャンセルボタンを押したら、ココから下を実行
header('HTTP/1.0 401 Unauthorized');
print('認証されませんでした');
}
else{
// 認証データがある場合は、それを表示する
print("<p>ユーザ名:".$_SERVER['PHP_AUTH_USER']."</p>\n");
print("<p>パスワード:".$_SERVER['PHP_AUTH_PW']."</p>\n");

// 認証データは、このスクリプトがあるディレクトリおよびそれ以下でのみ取得可
}

?>
</body>
</html>

PEARエクステンションのAuthパッケージを利用する場合

PEARエクステンション、必要となるパッケージのインストール


[root@localhost ~]# yum install php-pear

[root@localhost ~]# pear install Auth
Starting to download Auth-1.6.1.tgz (56,527 bytes)
..............done: 56,527 bytes
install ok: channel://pear.php.net/Auth-1.6.1

[root@localhost ~]# pear install DB
Starting to download DB-1.7.13.tgz (132,246 bytes)
.............................done: 132,246 bytes
install ok: channel://pear.php.net/DB-1.7.13

[root@localhost ~]# pear list
Installed packages, channel pear.php.net:
=========================================
Package Version State
Archive_Tar 1.3.1 stable
Auth 1.6.1 stable
Console_Getopt 1.2 stable
DB 1.7.13 stable
PEAR 1.4.9 stable
XML_RPC 1.5.0 stable

PHPのソースコード


<html>
<body>
<?php

# use PEAR Auth package
require_once("Auth/Auth.php");

$params = array(
"dsn" => "mysql://authuser:mypass@192.168.1.66/auth_db",
"table" => "auth_tbl",
"usernamecol" => "user",
"passwordcol" => "password"
);

$auth = new Auth("DB", $params);
$auth->start();

if ($auth->getAuth()) {
print("<p>認証が成功しました</p>\n");
print("<p>ユーザ名:".$auth->getUsername()."</p>\n");
}
else{
print("<p>認証が失敗しました</p>");
}

?>
</body>
</html>

ログアウトのためのスクリプトは


<?php

# use PEAR Auth package
require_once("Auth/Auth.php");

$params = array(
"dsn" => "mysql://authuser:mypass@192.168.1.66/auth_db",
"table" => "auth_tbl",
"usernamecol" => "user",
"passwordcol" => "password"
);

$auth = new Auth("DB", $params);
$auth->start();

if ($auth->getAuth()) {
$auth->logout();
print("<p>ログアウトしました</p>\n");
}
else{
print("<p>認証していません</p>");
}

?>

なお、MySQL側に作成されている認証用テーブルは次のようになっている。パスワードはMD5ハッシュに変換されたものを格納しておく必要がある。 (このテーブルへのユーザ追加・パスワード変更のための簡易的なインターフェースのPHPスクリプトについては、こちらの記事へ


mysql> describe auth_tbl;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| idx | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(16) | NO | | NULL | |
| password | varchar(256) | NO | | NULL | |
| role | varchar(32) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> select * from auth_tbl;
+-----+---------+----------------------------------+------+
| idx | user | password | role |
+-----+---------+----------------------------------+------+
| 1 | myname | a029d0df84eb5549c641e04a9ef389e5 | NULL |
+-----+---------+----------------------------------+------+
1 row in set (0.00 sec)

この認証のデータはセッション変数として格納されているようで、クライアント側では


$_SERVER['HTTP_COOKIE'] = PHPSESSID=7hnctfcl7gfshda35cnkeo2rj3;authchallenge=cbbbe0dc44f8b8e9e4edd800f748a7c9

サーバ側では、


[root@localhost ~]# ls -la /var/lib/php/session
合計 36
drwxrwx--- 2 root www_group 4096 8月 9 14:55 .
drwxr-xr-x 3 root root 4096 5月 24 23:00 ..
-rw------- 1 www_user www_group 15 8月 9 14:55 sess_7hnctfcl7gfshda35cnkeo2rj3
-rw------- 1 www_user www_group 21589 8月 9 14:09 sess_Ok0qpquS4NC1IYss0oY2QkEHZl1

となっている。