プロトタイプでつまずいて…(2)

前回に続き、求人マッチングサイトのプロトタイプ開発、技術検証編です。
今回のプロトタイプでは、以下の点について、技術検証をしました。
1.特定のDBMSに依存しないコーディング
2.日本語メールの送信
3.認証処理
1.と2.は、特に問題ありませんでしたが、3.の認証処理で大きくつまずきました。


1.特定のDBMSに依存しないコーディング
PHPでデータベースにアクセスする方法として、対象のDBMS専用のAPIの他に、多くの書籍でPEAR::DBを紹介している様です。しかし、PEARの公式ページでもPEAR::DBではなくPEAR::MDB2の利用が推奨されていますので、今回は、PEAR::MDB2を使うことにしました。以前は、MySQLのAPIを使って開発していたので、多少の慣れが必要でしたが、MDB2に移行しても問題はありません。
こんな感じでコーディングしておけば、後でDBMSを変更するのも容易なはずです。(mysql以外ではテストしてませんが…)

require_once ('MDB2.php');
// データベース接続の設定
$dbms = 'mysql';
$db_host = 'localhost';
$db_name = 'poor_db';
$db_user = 'poor_se';
$db_psw = 'password';
$db_option = '?charset=utf8';
// データベースに接続
$mdb2 =& MDB2::factory("{$dbms}://{$db_user}:{$db_psw}@{$db_host}/{$db_name}{$db_option}");
if (PEAR::isError($mdb2)) { die($mdb2->getMessage()); }

ただし、Limit句など、MySQLに依存したSQLを使う場合があるので、本当の意味でDBMSに依存しないコーディングとは言えません。
2.日本語メールの送信
mb_send_mail(…)を使います。文字化けするという情報がありますが、言語と文字コードを正しく設定しておけば問題なさそうです。(文字コードは、html、PHPのスクリプト、データベース、全て合わせた方がよい。)

mb_language("ja");
mb_internal_encoding("UTF-8");

3.認証処理
今回の最大の難関で、全て解決するのに4日程かかりました。
事業者情報を更新したり求人を出したりできるのは登録済の事業者のみであり、自分自身に関してのみ実行できます。当然ですが、他の事業者の求人を勝手に出すことが出来てはいけません。
今回のシステムは、ご予算の関係もあり、特別にセキュリティレベルの高いものを作ることは出来ませんが、データベースでユーザIDとパスワードを管理し、ログイン中であるかどうかはPHPのセッションを使って確認する一般的な仕組みにします。自分でこの仕組みを作ることも出来ますが、今回はPEAR::Authを使うことにしました。結果として、自分で作った方が簡単だったかもしれません。
まず、開発環境にPEAR::Authをインストールし、ネットで集めた情報を便りにテストしてみますが、全く機能しません。そもそも、実行結果の情報が得られないので、何が起きているか全く判りません。
Authのデバッグ用ログを取得するために、PEAR::Logを導入。Authでログを取得する方法は下記のページを参考にしました。
http://php.atpedia.jp/pear/ja/package.authentication.auth.intro-logging.html
まず、自分のコーディングミスを発見。データベースの接続文字列が間違っていました。そのためユーザー管理のテーブルにアクセスすらしていませんでした。
次に、ユーザ管理のテーブル設計にミスがありました。ユーザー情報保護のため、パスワードだけでなくユーザIDもハッシュ値で格納することにしていたのですが、Authに外部から指定できるパラメータでは、ユーザIDの検索条件をハッシュ値に変換することは出来ません。もし、テーブルの設計をそのまま利用するなら、独自のステレージドライバ(下記参照)を作る必要があります。
http://php.atpedia.jp/pear/ja/package.authentication.auth.storage.custom.html
とりあえず、ユーザIDは他のユニークキーで代用して先に進めたのですが、今度はパスワードのハッシュ値の項目属性をバイナリ形式としていたので問題が生じました。バイナリ形式で格納していること自体は、Authに与えるパスワードの項目名をhex(password)とすることで解決できそうでしたが、なぜか、入力したパスワードのハッシュ値と、データベースに格納されたパスワードのハッシュ値を16進数文字列に変換したものが一致しません。どうやら、値は等しいのですが、16進数の表記が大文字か小文字かと言う問題で不一致になっている様です。ハッシュ値の大文字と小文字を区別する必要はないと思うのですが、Authの仕様が文字列で比較することになっているので回避できません。やむを得ず、テーブル定義をバイナリ形式から文字列に変更しました。そもそもバイナリ形式のままでは、phpMyAdminでデータをエクスポートする時に文字化けするので厄介でした。
なんとかログイン認証は成功したのですが、今度はWebページの設計上の問題が出てきました。
定義したログインFORMがいつどのタイミングで表示されるのか理解していなかったので、HTMLのcharsetを出力する前にログインFORMが出力されてしまい、文字化けしていました。これは、Authのstartメソッドを実行するタイミングで表示されることが判りましたので解決しましたが、HTMLの記述の中に、一見、HTMLの出力に関係なさそうなstartメソッドの記述が入るので、少し気持ちが悪いです。
さらに、認証の必要なページと、ログインページを別のスクリプトにしていたので、問題が出てきました。ログインしていなかったらログインページに遷移し、ログインが成功したら元のページに戻るという仕組みです。
元のページに戻るための情報は、セッション情報で渡すことが出来ますが、ログインページでエラーメッセージを表示するためのステータスが受け渡されません。どうやら、getAuthメソッドで認証済であるかどうかを確認する時にステータスが記録されるのですが、ログインページが別スクリプトになっているために、ステータスが受け渡されません。セッション情報を使って自分でステータスを受け渡すことは出来ますが、本来は、ログインページを別のスクリプトにする仕様にはなっていない様でした。
結局の所、Pear::Authの仕様を理解する前に、データベースや画面の設計をしていたために起きた問題です。でも、この様な問題点を見つけるのが技術検証の役割です。大変でしたが、技術検証としは上手く行ったということです。

“プロトタイプでつまずいて…(2)” への 1 件のフィードバック

コメントは受け付けていません。