1 package Plack::Middleware::Session;
6 our $AUTHORITY = 'cpan:STEVAN';
13 use parent 'Plack::Middleware';
15 use Plack::Util::Accessor qw(
24 $self->state( 'Cookie' ) unless $self->state;
25 $self->state( $self->inflate_backend('Plack::Session::State', $self->state) );
26 $self->store( $self->inflate_backend('Plack::Session::Store', $self->store) );
28 Plack::Util::load_class($self->session_class) if $self->session_class;
32 my($self, $prefix, $backend) = @_;
34 return $backend if defined $backend && Scalar::Util::blessed $backend;
37 push @class, $backend if defined $backend; # undef means the root class
40 Plack::Util::load_class(@class)->new();
47 my $request = Plack::Request->new($env);
49 my($id, $session) = $self->get_session($request);
50 if ($id && $session) {
51 $env->{'psgix.session'} = $session;
53 $id = $self->generate_id($request);
54 $env->{'psgix.session'} = {};
57 $env->{'psgix.session.options'} = { id => $id };
59 if ($self->session_class) {
60 $env->{'plack.session'} = $self->session_class->new($env);
63 my $res = $self->app->($env);
64 $self->response_cb($res, sub {
65 my $res = Plack::Response->new(@{$_[0]});
66 $self->finalize($env, $res);
67 $res = $res->finalize;
68 $_[0]->[0] = $res->[0];
69 $_[0]->[1] = $res->[1];
74 my($self, $request) = @_;
76 my $id = $self->state->extract($request) or return;
77 my $session = $self->store->fetch($id) or return;
79 return ($id, $session);
83 my($self, $request) = @_;
84 $self->state->generate($request);
90 my $session = $env->{'psgix.session'};
91 my $options = $env->{'psgix.session.options'};
93 if ($options->{expire}) {
94 $self->store->remove($options->{id});
96 $self->store->store($options->{id}, $session);
101 my($self, $env, $response) = @_;
103 my $session = $env->{'psgix.session'};
104 my $options = $env->{'psgix.session.options'};
106 $self->commit($env) unless $options->{no_store};
107 if ($options->{expire}) {
108 $self->expire_session($options->{id}, $response, $env);
110 $self->save_state($options->{id}, $response, $env);
115 my($self, $id, $res, $env) = @_;
116 $self->state->expire_session_id($id, $res, $env->{'psgix.session.options'});
120 my($self, $id, $res, $env) = @_;
121 $self->state->finalize($id, $res, $env->{'psgix.session.options'});
132 Plack::Middleware::Session - Middleware for session management
140 my $session = $env->{'psgix.session'};
143 [ 'Content-Type' => 'text/plain' ],
144 [ "Hello, you've been here for ", $session->{counter}++, "th time!" ],
153 # Or, use the File store backend (great if you use multiprocess server)
154 # For more options, see perldoc Plack::Session::Store::File
156 enable 'Session', store => 'File';
162 This is a Plack Middleware component for session management. By
163 default it will use cookies to keep session state and store data in
164 memory. This distribution also comes with other state and store
165 solutions. See perldoc for these backends how to use them.
167 It should be noted that we store the current session as a hash
168 reference in the C<psgix.session> key inside the C<$env> where you can
171 B<NOTE:> As of version 0.04 the session is stored in C<psgix.session>
172 instead of C<plack.session>.
174 Also, if you set I<session_class> option (see below), we create a
175 session object out of the hash reference in C<plack.session>.
181 =item L<Plack::Session::State>
183 This will maintain session state by passing the session through
184 the request params. It does not do this automatically though,
185 you are responsible for passing the session param.
187 =item L<Plack::Session::State::Cookie>
189 This will maintain session state using browser cookies.
197 =item L<Plack::Session::Store>
199 This is your basic in-memory session data store. It is volatile storage
200 and not recommended for multiprocessing environments. However it is
201 very useful for development and testing.
203 =item L<Plack::Session::Store::File>
205 This will persist session data in a file. By default it uses
206 L<Storable> but it can be configured to have a custom serializer and
209 =item L<Plack::Session::Store::Cache>
211 This will persist session data using the L<Cache> interface.
213 =item L<Plack::Session::Store::Null>
215 Sometimes you don't care about storing session data, in that case
216 you can use this noop module.
222 The following are options that can be passed to this mdoule.
228 This is expected to be an instance of L<Plack::Session::State> or an
229 object that implements the same interface. If no option is provided
230 the default L<Plack::Session::State::Cookie> will be used.
234 This is expected to be an instance of L<Plack::Session::Store> or an
235 object that implements the same interface. If no option is provided
236 the default L<Plack::Session::Store> will be used.
238 It should be noted that this default is an in-memory volatile store
239 is only suitable for development (or single process servers). For a
240 more robust solution see L<Plack::Session::Store::File> or
241 L<Plack::Session::Store::Cache>.
243 =item I<session_class>
245 This can be used to create an actual session object in
246 C<plack.session> environment. Defaults to none, which means the
247 session object is not created but you can set C<Plack::Session> to
248 create an object for you.
254 All complex software has bugs lurking in it, and this module is no
255 exception. If you find a bug please either email me, or add the bug
262 Stevan Little E<lt>stevan.little@iinteractive.comE<gt>
264 =head1 COPYRIGHT AND LICENSE
266 Copyright 2009, 2010 Infinity Interactive, Inc.
268 L<http://www.iinteractive.com>
270 This library is free software; you can redistribute it and/or modify
271 it under the same terms as Perl itself.