はじめに

本サイトはCodeIgniterとその認証ライブラリTank AuthをPostgreSQL上で利用する場合のTipsについてまとめたサイトです。
途中まで作成して、素直にMySQLにすればいい気もしてきましたがPostgreSQLユーザの方の参考になればと思いまとめてみました。

環境

CodeIgniter 2.0.1
Tank Auth 1.0.9 認証用ライブラリ
※Tank Authは利用するDBがMySQLを基本としておりPostgreSQLを利用しようとした場合、修正が必要となります。
PostgreSQL対応版としてリメイクしたので以下からダウンロードしてください。
※ただし ・Tank Auth 1.0.9 認証用ライブラリ(PostgreSQL対応版)
・PostgreSQL 8.2
・php 5.2.5

文字コード

・データベース UTF-8
・CodeIgniter Tank Authの各種ファイル SHIFT JIS(普通にインストールした場合のそのままの文字コード)

インストール方法

CodeIgniter 2.0

http://codeigniter.jp/user_guide_ja/installation/index.html

Tank Auth 1.0.9 認証用ライブラリ(PostgreSQL対応版)のインストール手順

基本的にTank Authの手順に準じています。

手順説明
1tank_auth_postgresql-1.0.9-0.2.zipを適当なフォルダで展開する
2展開すると[application],[captcha],[system]があるので[application]はciの[application]フォルダに上書き
[captcha]は[application]フォルダと同じ階層にコピーする。※ディレクトリ構成をカスタマイズした時は変更が必要なので
その場合は参考URLを確認してください。
[system]はCodeIgniter(フレームワーク)のファイルを一部更新しているため、内容をご確認の上上書きしてください。
3schema.postgresql.sqlのSQLを利用してテーブルを作成する。
作成方法はpgsqlまたは、pgAdminなどで作成できます。
4 application/config/config.phpを修正します。
1. $config['sess_use_database'] を TRUEにします。
2. $config['encryption_key'] に任意の値(下記の例では samplekey)を設定します。
$config['encryption_key'] = 'samplekey';   // ★
// ~
$config['sess_cookie_name']		= 'ci_session';
$config['sess_expiration']		= 7200;
$config['sess_expire_on_close']	= FALSE;
$config['sess_encrypt_cookie']	= FALSE;
$config['sess_use_database']	= TRUE;   // ★
$config['sess_table_name']		= 'ci_sessions';
$config['sess_match_ip']		= FALSE;
$config['sess_match_useragent']	= TRUE;
$config['sess_time_to_update']	= 300;
5 application/config/database.phpを修正し、Tank Auth用に作成したテーブルにアクセスできるようにします。
既に設定済みであれば不要です。
以下の例で[dbdriver]に設定している'postgre'以外の値は各自の環境にあわせて変更してください。
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'usr1';
$db['default']['password'] = 'pwd1';
$db['default']['database'] = 'ci';
$db['default']['dbdriver'] = 'postgre';
6 system/libraries/Email.phpを修正し、メールが送信できるようにします。
既に設定済みであれば不要です。
各自の環境にあわせて変更してください。
var	$protocol		= "smtp";	// mail/sendmail/smtp
var	$smtp_host		= "smtp.s-proj.com";		// SMTP Server.  Example: mail.earthlink.net
var	$smtp_user		= "user@s-proj.com";		// SMTP Username
var	$smtp_pass		= "pwd";		// SMTP Password
var	$smtp_port		= "25";		// SMTP Port

Tank Auth 1.0.9

  ★PostgreSQL対応版をインストールすれば作業は不要です。
http://www.konyukhov.com/soft/tank_auth/
http://www.playing-engineer.com/download/ci_auth/
http://kokudori.blog69.fc2.com/blog-entry-7.html

確認方法

手順説明
1 以下のURLにアクセスします。
http://[localhost/ci ここは各自の環境にあわせてください]/index.php/auth/login
htaccessを指定している場合は
http://[localhost/ci ここは各自の環境にあわせてください]/auth/login
でもOKです。
正常に動作すると以下のような画面が表示されます。


2 画面上のRegisterのリンクをクリックすると以下の画面が表示されるので
必要な情報を入力し、[Register]ボタンを押下してください。

3 登録が完了すると登録したメールアドレスに以下のようなメールが送信されます。
中に記載されているURLをクリックすればユーザ登録まで完了です。

Welcome to Your project,

Thanks for joining Your project. We listed your sign in details below, make
sure you keep them safe.
To verify your email address, please follow this link:

http://localhost/ci/index.php/auth/activate/1/41b9fccc4c4c63726b1357166d00e060

Please verify your email within 48 hours, otherwise your registration will
become invalid and you will have to register again.

Your username: xxxx
Your email address: xxxx@s-proj.com

Have fun!
The Your project Team

認証ページの作成方法

実際にログインした場合にのみアクセスできる認証ページを作成してみましょう。
参考になるのはTank Auth(PostgreSQL版 通常版とも)に格納されている以下のファイルです。

application/controllers/welcome.php

ログインしていない状態で直接アクセスしようとするとログインページに戻され、
ログインしていると画面が表示できます。
load->helper('url');
		$this->load->library('tank_auth');
	}

	function index()
	{
		if (!$this->tank_auth->is_logged_in()) {
			redirect('/auth/login/');
		} else {
			$data['user_id']	= $this->tank_auth->get_user_id();
			$data['username']	= $this->tank_auth->get_username();
			$this->load->view('welcome', $data);
		}
	}
}
流れとしては、認証ページのcontrollerの先頭で$this->tank_auth->is_logged_in()でログイン可否を判定し
ログインしていない場合はログインページにリダイレクト、ログインしている場合はそのまま画面を表示といった
流れです。

Tank Auth 1.0.9 認証用ライブラリ(PostgreSQL対応版)の修正内容

修正箇所は以下の点です。

・schema.sql→schema.postgresql.sql

テーブル作成時のデータの属性の設定方法が異なるため、以下のサイトを参考にさせていただきました。
http://snipplr.com/view/41740/create-tables-for-the-codeigniter-library--tank-auth-in-postgresql/
ただし、上記のsqlですと 処理の途中でテーブル[ci_sessions]の[user_data]のNOT NULL 制約でエラーが発生します。
これはMySQLとPostgreSQLの NOT NULL属性の挙動が異なり、MYSQLの場合、NOT NULL属性のカラムに何も値が無い状態で登録しようとすると
データベースが適切と思われる値を自動的に設定しエラーが発生しないのに対しPostgreSQLはエラーとしているためです。
http://dev.mysql.com/doc/refman/5.1/ja/constraint-invalid-data.html

(以下参照元抜粋)
厳格モードを使用していない場合、NOT NULLカラムにおけるNULLや数値カラムにおける大きすぎる数値のように
「正しくない」 値をカラムに挿入すると、MySQL ではエラーを生成するのではなく、カラムを「最適可能値」に設定します。
この動作規則について、以下に詳しく説明します。
数値カラムに範囲外の値を格納しようとすると、代わりにMySQLサーバは0、
使用可能な最小値、または使用可能な最大値(いずれも無効値に近い値)を 格納します。
文字列については、MySQLは空白文字列、またはカラム内で格納可能な最長文字列を格納します。

ここまで

そのため以下のように、NOT NULL属性とあわせ DEFAULT属性を設定してみました。
user_data text NOT NULL DEFAULT '',

・application/models/tank_auth/login_attempts.php ,users.php

プログラム内部のSQL文で日付の判定のためにUNIX_TIMESTAMP()という関数を使っていますがこれは
PostgreSQLではサポートされていません。
そのため、以下のサイトを参考に修正を行いました。
http://www.raditha.com/postgres/timestamp.php
また、影響範囲を抑えるため、dbdriverの設定が[postgre]の場合(つまりPostgreSQLを利用する場合)のみ、修正したルートを通り、
それ以外の場合は以前のコードを使うようにしておきましたので、本コードを利用してMySQLを使う事も可能です。(動作は未確認)
tank_auth_postgresql-1.0.9-0.2.zipでは以下の日本語対応分のソースも含まれていますので個別の環境設定のみで対応可能となっています。

日本語対応

データベースとの接続

今回の環境の場合クライアント(SJIS)→サーバ(utf-8)のため、client_encodingでクライアント側のエンコード(SJIS)を
設定する必要があります。
設定を行わなかった場合、以下のエラーがユーザ登録(Register)時に発生する可能性があります。
データベースエラーが発生しました。
Error Number:
ERROR: invalid byte sequence for encoding "UTF8": 0x93 HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
UPDATE ci_sessions SET "last_activity" = 1309932679, "user_data" = 'a:3:{s:22:"flash:old:captcha_word";s:8:"JriWCmHK";s:22:"flash:old:captcha_time";d:1309932698.7227480411529541015625;s:17:"flash:new:message";s:64:"?o?^????????B?A?J?E???g??L???????2???[????m?F?????????B";}' WHERE "session_id" = '1cc12744f05b841397c71d8f25271f1b'
Filename: XXXXX\system\database\DB_driver.php


また、今回利用しているCodeIgniter 2.0.1ではPostgreSQLのクライアントエンコーディングの設定は
todo項目のようで未実装のため、フレームワークに一部手をいれる必要があります。

手順説明
1 application/config/database.phpを修正し、クライアントのエンコード種別を指定します。

以下の例で$db['default']['char_set']にクライアントのエンコード[SJIS]を設定しています。
$db['default']['dbdriver'] = 'postgre';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'SJIS';  // ★
2 system/database/drivers/postgre/postgre_driver.php( 148行目付近)を修正し、クライアントエンコーディングの設定を実装します。
	function db_set_charset($charset, $collation)
	{
		// @todo - add support if needed
		return @pg_exec($this->conn_id, "SET client_encoding TO '".$this->escape_str($charset)."'");  // ★ 修正後
//		return TRUE;  修正前
	}

メールの日本語化

Tank Authを利用すると各種通知がメールで送信されてきます。
ここではこのメールの内容を日本語化する手順について整理します。
作業としては、
1)日本語(マルチバイト対応)のメールが送信できるようにする、
2)日本語のメールの文面を作成し、登録する、
3)現在登録されている日本語のsubjectを修正するといった作業が必要です。
3)はサービス名とユーザ名を混同しているような訳になっているので単純な翻訳ミスではと思われます。


手順説明
1 1)日本語(マルチバイト対応)のメールが送信できるようにする
・system/libraries/Email.phpへメール送信のための設定を行う。
※この作業はインストール手順の中での作業と同じ内容なので省略します。
作業済みであれば不要です。

・application/config/email.phpへメール送信のための設定を行う。
以下のサイトを参考にさせていただきました。
http://blog.promob.jp/fri/2009/11/codeigniteremail.html


$config['mailtype'] = 'txt';  // ★ここはテキストベースのメールがhtmlベースのメールかを指定します。
$config['charset'] = 'iso-2022-jp';  // ★
$config['newline'] = '\r\n';


・system/libraries/Email.phpも修正 _preq_q_encodeingをコメントアウト
http://blog.livedoor.jp/trisys/archives/747631.html


function subject($subject)
    {
//   ★     $subject = $this->_prep_q_encoding($subject);
        $this->_set_header('Subject', $subject);
    }


・application/controllers/auth.phpをマルチバイト対応に修正する。
    function _send_email($type, $email, &$data)
    {

        $this->load->library('email');
// 修正前
//		$this->email->from($this->config->item('webmaster_email', 'tank_auth'), $this->config->item('website_name', 'tank_auth'));
//		$this->email->reply_to($this->config->item('webmaster_email', 'tank_auth'), $this->config->item('website_name', 'tank_auth'));
//		$this->email->to($email);
//		$this->email->subject(sprintf($this->lang->line('auth_subject_'.$type), $this->config->item('website_name', 'tank_auth')));
//		$this->email->message($this->load->view('email/'.$type.'-html', $data, TRUE));
//		$this->email->set_alt_message($this->load->view('email/'.$type.'-txt', $data, TRUE));

// ★修正後
        $from_name = mb_encode_mimeheader($this->config->item('website_name', 'tank_auth'), "ISO-2022-JP","SJIS");
        $subject = mb_convert_encoding(sprintf($this->lang->line('auth_subject_'.$type), $this->config->item('website_name', 'tank_auth')), "ISO-2022-JP", "SJIS");
		// 2)の多言語化対応のため、languageの指定により参照するディレクトリが変わるようにしています。
        $message = mb_convert_encoding($this->load->view('email/language/'.$this->config->item('language')."/".$type.'-txt', $data, TRUE), "ISO-2022-JP", "SJIS");
		// 2)の多言語化対応のため、languageの指定により参照するディレクトリを変わるようにしています。
        $alt_message = mb_convert_encoding($this->load->view('email/language/'.$this->config->item('language')."/".$type.'-txt', $data, TRUE), "ISO-2022-JP", "SJIS");
        $this->email->from($this->config->item('webmaster_email', 'tank_auth'), $from_name);
        $this->email->reply_to($this->config->item('webmaster_email', 'tank_auth'), $from_name);
        $this->email->to($email);
        $this->email->subject($subject);
        $this->email->message($message);
        $this->email->set_alt_message($alt_message);

        $this->email->send();
    }

2 2)日本語のメールの文面を作成し、登録する。
メールの文面はapplication/views/email配下に登録されているため、これらのファイルを直接日本語に変更すればよいのですが、
少し工夫をして多言語化対応チックに修正します。ただし、ソース中に埋め込まれているところなどもあるので中途半端といえば中途半端ですが。。

新規にディレクトリを作成し、その配下に文章の元ネタのファイルを格納します。。
application/views/email/language/english 英語版(現在はいっているファイルをapplication/views/emailにはいっているファイルを移動)
application/views/email/language/japanese 日本語版(英語版を翻訳したもの)

・application/controllers/auth.phpを多言語化対応に修正する。
→修正内容は1)の中に記述しています。
3 3)現在登録されている日本語のsubjectを修正する。
・application/language/japanese/tank_auth_lang.phpを修正します。
下記はあくまで参考ですのでシステムにあわせて修正してください。
// Email subjects 修正前
//$lang['auth_subject_welcome'] = 'ようこそ %s さん!';
//$lang['auth_subject_activate'] = 'ようこそ %s さん!';
//$lang['auth_subject_forgot_password'] = ' %s のパスワードをお忘れですか?';
//$lang['auth_subject_reset_password'] = '%s の新らしいパスワード';
//$lang['auth_subject_change_email'] = '%s の新しいメールアドレス';
// Email subjects ★修正後
$lang['auth_subject_welcome'] = '%s へようこそ!';
$lang['auth_subject_activate'] = '%s へようこそ!';
$lang['auth_subject_forgot_password'] = ' %s のパスワードをお忘れですか?';
$lang['auth_subject_reset_password'] = '%s のパスワードを変更しました';
$lang['auth_subject_change_email'] = '%s の登録メールアドレスを変更しました';


著作権等

Tank Authの著作権に準じたいのですが、HPを見ても確認できなかったため、確認できるまで暫定的にMITライセンスといたします。
個人、商用含め自由にご利用いただけます。
ただし、いかなる理由により損害等が発生しても当サイトは一切責任をもちません。

お問合わせ、ご質問等

mail address

その他のサイト

Top
オンライン戦略ボード
祝日判定webAPI
もんじゅリアル
CodeIgniter + PostgreSQL

ページ更新日

2012.3.7 メールの日本語対応を一部追加
2011.7.6 日本語対応版のPostgreSQL対応版をアップ
2011.7.5 サイトアップ