IDとパスワードでログインして、ユーザの権限で画面が違ったりするっていう感じのことをしなくてはいけなくなったので、考えてみました。
ファイル構成
/my_app
/my_app/lib
/my_app/lib/MyApp.pm
/my_app/lib/MyApp/Admin.pm
/my_app/lib/MyApp/Model/Login.pm
/my_app/log
/my_app/public
/my_app/script
/my_app/script/my_app
/my_app/script/my_app.psgi
/my_app/session --ここにセッションファイルが溜まる
/my_app/t
/my_app/templates
/my_app/templates/layout
/my_app/templates/admin/login.html.ep
/my_app/templates/admin/logout.html.ep
/my_app/templates/admin/mainpage.html.ep
だいたいこんな感じです。
本番ではもう少し変える(し、かなり増える)と思います。
肝になるファイルの内容
/my_app/script/my_app.psgi
use strict;
use warnings;
use Mojo::Server::PSGI;
use Plack::Builder;
use Plack::Session::Store::File;
use Plack::Session::State::Cookie;
use YAML;
use FindBin;
BEGIN { unshift @INC, "$FindBin::Bin/../lib" }
use MyApp;
my $psgi = Mojo::Server::PSGI->new( app => MyApp->new );
my $app = $psgi->to_psgi_app;
builder {
enable 'Session',
state => Plack::Session::State::Cookie->new(
#secure => 1, SSL通信する場合は必要だけど、今回は試してみただけなのでコメントアウト
httponly => 1
),
store => Plack::Session::Store::File->new(
dir => '../session', #指定しないと /tmp 直下に保存されちゃう。
serializer => sub { YAML::DumpFile( reverse @_ ) },
deserializer => sub { YAML::LoadFile( @_ ) },
);
$app;
};
/my_app/lib/MyApp.pm
package MyApp;
use Mojo::Base 'Mojolicious';
sub startup {
my $self = shift;
$self->helper(testsession => sub {
my $self = shift;
my $env = $self->req->env;
return $env->{'psgix.session'};
});
#↑のhelperを使うと、コントローラーで受け取る$selfにメソッド追加できる
#ので、Plackで持っている(?)セッションにアクセスできるようにしておく
# Router
my $r = $self->routes;
my $logged_in = $r->bridge->to('admin#login');
#↑で作ったbridgeは、権限が係るすべてのページで使う
#誰でも見ていいページの場合は、$r->get('/hoge')->to('hoge#piyo')とかで
$logged_in->get('/')->to('admin#mainpage');
}
1;
/my_app/lib/MyApp/Admin.pm
package MyApp::Admin;
use Mojo::Base 'Mojolicious::Controller';
use MyApp::Model::Login;
sub mainpage {
my $self = shift;
$self->render();
}
sub login {
my $self = shift;
#Modelのログインがらみの部分を呼び出してログイン状態の判定をさせる感じ
#そっちの処理はセッション確認したりDBと照合したりするかんじ。今回はどうでもいい
my $login = MyApp::Model::Login->new();
my $params = {};
$params->{user_id} = $self->param('user_id') if( $self->param('user_id') && $self->param('user_id') =~ /^[a-zA-Z0-9]+$/ );
$params->{password} = $self->param('password') if( $self->param('password') && $self->param('password') =~ /^[a-zA-Z0-9]+$/ );
my $login_status = $login->proc_login($params);
$self->rendar( error_msg => $login_status->{error} ) if ( $login_status->{error} );
return $login_status->{status};
}
sub logout{
my $self = shift;
#ログアウトしたら、セッション書き換えて終了
#ほんとはもう少しちゃんとした処理が入ると思う
$self->testsession->{'login_status'} = 'logout';
return 1;
}
1;
という雰囲気でできそうです。
細かいネーミングとかはかなりテキトーです。
その他含めてベストかどうかはわかりませんが、なんとかできそうなので安心しました。