Catalystでユーザ認証処理をする
Catalystで簡易なユーザ認証処理を実装します。
- 前提条件
- MySQL5.0.x
・テーブルとレコード作成
CREATE TABLE users ( id integer NOT NULL auto_increment PRIMARY KEY, username varchar(20) NOT NULL, password varchar(30) NOT NULL ) ENGINE=InnoDB; INSERT INTO users(username, password) VALUES('test01', 'passwd');
・usersテーブルのSchemaを生成する
./script/myapp_create.pl model MyAppDB DBIC::Schema MyAppDB create=static 'dbi:mysql:test;;mysql_socket=/tmp/mysql.sock' root root exists "/who/am/i/MyApp/script/../lib/MyApp/Model" exists "/who/am/i/MyApp/script/../t" Dumping manual schema for MyAppDB to directory /who/am/i/MyApp/script/../lib ...Schema dump completed. created "/who/am/i/MyApp/script/../lib/MyApp/Model/DBIC.pm" exists "/who/am/i/MyApp/script/../t/model_DBIC.t"
以下のファイルが生成されます
./lib/MyApp/Model/MyAppDB.pm ./lib/MyAppDB.pm ./lib/MyAppDB/Users.pm ./t/model_MyAppDB.t
・設定ファイル(myapp.yml)に認証情報を追加する。
$ vi ./myapp.yml +authentication: + dbic: + user_class: MyAppDB::Users + user_field: username + password_field: password
・アプリケーションクラス(./lib/MyApp.pm)に必要なCPANモジュールを 指定 する。
use Catalyst qw/ -Debug ConfigLoader Static::Simple StackTrace Authentication Authentication::Store::DBIC Authentication::Credential::Password Session Session::Store::FastMmap Session::State::Cookie /;
・Login、Logoutコントローラ生成
$ ./script/myapp_create.pl controller Login $ ./script/myapp_create.pl controller Logout
・Login(MyApp::Controller::Login)コントローラ編集
sub index : Private { my ( $self, $c ) = @_; # Get the username and password from form my $username = $c->req->param->{username} || ''; my $password = $c->req->param->{password} || ''; # If the username and password values were found in form if ($username && $password) { # Attempt to log the user in if ($c->login($username, $password)) { # If successful, then let them use the application $c->stash->{logined} = 1; $c->stash->{username} = $username; } else { # Set an error message; $c->stash->{error_msg} = 'ユーザ名、もしくはパスワードが間違っています'; } } $c->stash->{template} = 'login.tt'; }
・Logout(MyApp::Controller::Logout)コントローラ編集
sub index : Private { my ( $self, $c ) = @_; # Clear the user's state $c->logout; # Send the user to the starting point $c->res->redirect( '/login' ); }
・login.tt(./root/tmpl/login.tt) 作成
[% IF logined %] ようこそ [% username %] さん! <br /> <br /> ログインに成功しました。<br /> <br /> [% ELSIF username %] [% username %] さんは既にログインされています。<br /> <br /> [% ELSE %] [% IF error_msg %] <font color="red">[% error_msg %]</font> [% END %] [% END %] <!-- Login form --> <form method="post" action="[% c.uri_for('login') %]"> <table> <tr> <td>Username:</td> <td><input type="text" name="username" size="40" /></td> </tr> <tr> <td>Password:</td> <td><input type="password" name="password" size="40" /></td> </tr> <tr> <td colspan="2"><input type="submit" name="submit" value="Submit" /></td> </tr> </table> </form>
・コントローラークラスの Root.pm の auto アクションに、セッション情報保持を追加
sub auto : Private { my ( $self, $c ) = @_; $c->stash->{username} = $c->session->{_user}; 1; }
・備考
ヘルパースクリプトではまりました。。
他のサイトでは、以下のようにヘルパースクリプトのコマンドが書いてありますが、
script/MyApp_create.pl model DBIC DBIC::Schema MyApp::Schema create=static dbi:mysql:dbname=MyAppDB MyAppUser Password
自分の環境だと、$c->login を呼んだときに以下のエラーが出ました。他の人は出てないんだろうなぁ。う〜ん。
Caught exception in MyApp::Controller::Login->index "Can't locate object method "search" via package "MyApp::Schema::Users" at /where/cpan-lib/lib/perl5/site_perl/5.8.5/Catalyst/Plugin/Authentication/Store/DBIC/User.pm line 31."
解決策は上述のとおり、ヘルパースクリプトの引数を変更しました。
- script/MyApp_create.pl model DBIC DBIC::Schema MyApp::Schema create=static dbi:mysql:dbname=MyAppDB MyAppUser Password + script/MyApp_create.pl model MyAppDB DBIC::Schema MyAppDB create=static dbi:mysql:dbname=MyAppDB MyAppUser Password