セッション管理を行う
Catalystでセッション管理を行うプラグインとしてはCatalyst::Plugin::Sessionネームスペース以下にたくさん用意されていますが、最近のバージョンでは廃止予定(DEPRECATED)となっているものもたくさんあるので注意が必要です。
CPANにはCatalyst::Plugin::Session::Tutorialという、Catalystでセッション管理を行うためのチュートリアルドキュメントが用意されており、セッションとは何か、セキュリティリスクにはどのようなものがあるか、などCatalystに依存しないセッション管理の基本的な情報が記述されていますのでご一読をおすすめします。
ステートレスなプロトコルであるHTTPを使って、どのユーザからリクエストされたのかを管理するためにセッションは使われますが、具体的にはサーバ側でユーザ固有の情報を管理する仕組みと、クライアント側でそのユーザ固有情報にひもづけるためのセッションIDを管理する仕組みに分かれます。
Catalystでは、それぞれCatalyst::Plugin::Session::StoreとCatalyst::Plugin::Session::Stateネームスペース以下にさまざまなプラグインが用意されています。
サーバ側でセッション情報を保存する
Catalyst::Plugin::Session::Storeネームスペース以下の主要なプラグインには次のようなものがあります。
Plugin名(Catalyst::Plugin::Sessionを省略) | 説明 |
Store::File | セッションデータをファイルに保存 |
Store::FastMmap | セッションデータをメモリマップトファイルに保存 |
Store::Memcached | セッションデータをmemcachedサーバに保存 |
Store::DBIC | セッションデータをDBIx::Class対応データベースに保存 |
Store::DBI | セッションデータをDBI対応データベースに保存 |
それぞれの開発環境やWebアプリケーションの規模に応じて選択してください。
クライアント側でセッションIDを管理する
セッションIDを管理するための、Catalyst::Plugin::Session::Stateネームスペース以下の主要なプラグインには次のようなものがあります。
Plugin名(Catalyst::Plugin::Sessionを省略) | 説明 |
State::Cookie | セッションIDのやりとりにCookieを使用 |
State::URI | セッションIDのやりとりにURIを使用 |
State::Stash | セッションIDのやりとりにStashを使用 |
URIにセッションIDを使う場合には、セッションハイジャックなどのセキュリティリスクがあり、通常はCookieを使用する場合が多いですが、携帯サイトなど端末によってはCookieに対応していないものもあり、URIにセッションIDをつけざるを得ない場合もあります。
このような場合には、キャリアのIPアドレスやUser-Agentをチェックするなどの対策を入れて、セキュリティリスクを減らす対策をお忘れなく。
Sessionプラグインを使う
今回のサンプルでは、サーバ側のセッション情報保持にCatalyst::Plugin::Session::Store::Fileを、セッションIDの管理にはCatalyst::Plugin::Session::State::Cookieを使うことにします。
それぞれのプラグインをインストールしましょう。
# perl -MCPAN -e 'install Catalyst::Plugin::Session::Store::File'
# perl -MCPAN -e 'install Catalyst::Plugin::Session::State::Cookie'
インストールできたら、まずはこれらのプラグインを使用するための設定を行います。最初にWebアプリケーションからSessionプラグインを登録します。
# 省略 use Catalyst qw/ -Debug ConfigLoader Static::Simple Session Session::State::Cookie Session::Store::File /;
次に、それぞれのSessionプラグインについて、セッション情報を保存するためのパス情報などを設定します。
# 省略 __PACKAGE__->config( name => 'AppSample', # 省略 # セッション関連のパラメータ登録 'Plugin::Session' => { expires => 1800, verify_user_agent => 1, verify_address => 1, cookie_expires => 0, }, );
Session関連のパラメータには、プラグインによってそれぞれ次のような値を設定することができます。
Plugin | パラメータ名 | 説明 | デフォルト値 |
Session | expires | セッションの有効期限(秒) | 7200(2時間) |
verify_address | セッション操作前にクライアントのIPアドレスをチェックし、セッション初期化時と異なれば削除する | 0 | |
verify_user_agent | セッション操作前にクライアントのUser-Agentをチェックし、セッション初期化時と異なれば削除する | 0 | |
Session::State::Cookie | cookie_name | Cookieの名前 | <MyApp>_session |
cookie_expires | Cookieの有効期限(秒)expiresの値 | ||
cookie_secure | HTTPS経由の場合のみCookieを送信するか | 0 | |
cookie_httponly | HttpOnly属性を使用するかどうか | 1 | |
cookie_path | Cookieの返送先として有効なWebサイトのパス | Webアプリケーションのルート | |
Session::Store::File | storage | セッションデータの保存先となるディレクトリ | システムのテンポラリファイルディレクトリ |
namespace | セッションデータを識別するためのネームスペース | ||
cache_depth | ディレクトリ階層の深さ | 3 | |
directory_umask | ディレクトリに設定するumaskの値 | 000 |
セッションを使用した例として、セッションデータにアクセスした数を保存する処理を実装してみましょう。セッションデータへアクセスするには「$c->session->{key}」のように指定します。
sub session_counter :Local { my ( $self, $c ) = @_; # (1)セッションから値を取得 my $counter = $c->session->{counter} || 1; # (2)カウンタの値を表示 $c->response->body("AccessCounter:${counter}"); # (3)カウンタの値+1してセッションに保存 $c->session->{counter} = ++$counter; }
セッションから値を取得するには(1)のように、keyとしてcounterを指定してsessionメソッドを呼び出しています。一番最初のアクセスでは値が設定されていないため、1で初期化する処理を加えています。
セッションに値を保存するには(3)のように、$counterに1加えた値を設定しています。ブラウザでアクセスした画面は次のようになります。
このサンプルでは、ファイルにセッションデータを保存しているので、Catalystアプリケーションを再起動した場合でも、セッションデータはクリアされません。
ちなみに、上記の設定値に置いてはLinux環境だとセッションデータは「/tmp/appsample/session/data」以下に保存されています。
$ ls -F /tmp/appsample/session/data
▼
5/ 6/ 8/ a/