Commit | Line | Data |
d326e755 |
1 | package Plack::Middleware::Session::Cookie; |
2 | use strict; |
3 | use parent qw(Plack::Middleware::Session); |
4 | |
09db0676 |
5 | use Plack::Util::Accessor qw(secret session_key domain expires path secure httponly); |
d326e755 |
6 | |
7 | use Digest::HMAC_SHA1; |
8 | use MIME::Base64 (); |
9 | use Storable (); |
10 | use Time::HiRes; |
11 | use Plack::Util; |
12 | |
13 | use Plack::Session::State::Cookie; |
14 | |
15 | sub prepare_app { |
16 | my $self = shift; |
17 | |
d326e755 |
18 | $self->session_key("plack_session") unless $self->session_key; |
19 | |
dc556d28 |
20 | $self->state( Plack::Session::State::Cookie->new ); |
09db0676 |
21 | for my $attr (qw(session_key path domain expires secure httponly)) { |
dc556d28 |
22 | $self->state->$attr($self->$attr); |
d326e755 |
23 | } |
dc556d28 |
24 | } |
25 | |
26 | sub get_session { |
27 | my($self, $request) = @_; |
28 | |
29 | my $cookie = $self->state->get_session_id($request) or return; |
d326e755 |
30 | |
dc556d28 |
31 | my($time, $b64, $sig) = split /:/, $cookie, 3; |
32 | $self->sig($b64) eq $sig or return; |
33 | |
f6abc0a3 |
34 | # NOTE: do something with $time? |
35 | |
dc556d28 |
36 | my $session = Storable::thaw(MIME::Base64::decode($b64)); |
f6abc0a3 |
37 | return ($self->generate_id, $session); |
d326e755 |
38 | } |
39 | |
dc556d28 |
40 | sub generate_id { |
41 | my $self = shift; |
f6abc0a3 |
42 | return scalar Time::HiRes::gettimeofday; |
dc556d28 |
43 | } |
4ff41723 |
44 | |
dc556d28 |
45 | sub commit { } |
46 | |
47 | sub save_state { |
7518e927 |
48 | my($self, $id, $res, $env) = @_; |
dc556d28 |
49 | |
7518e927 |
50 | my $cookie = $self->_serialize($id, $env->{'psgix.session'}); |
51 | $self->state->finalize($cookie, $res, $env->{'psgix.session.options'}); |
4ff41723 |
52 | } |
53 | |
d326e755 |
54 | sub _serialize { |
dc556d28 |
55 | my($self, $id, $session) = @_; |
d326e755 |
56 | |
d326e755 |
57 | my $b64 = MIME::Base64::encode( Storable::freeze($session), '' ); |
dc556d28 |
58 | join ":", $id, $b64, $self->sig($b64); |
d326e755 |
59 | } |
60 | |
61 | sub sig { |
62 | my($self, $b64) = @_; |
63 | return '.' unless $self->secret; |
64 | Digest::HMAC_SHA1::hmac_sha1_hex($b64, $self->secret); |
65 | } |
66 | |
67 | 1; |
68 | |
69 | __END__ |
70 | |
71 | =head1 NAME |
72 | |
73 | Plack::Middleware::Session::Cookie - Session middleware that saves session data in the cookie |
74 | |
75 | =head1 SYNOPSIS |
76 | |
77 | enable "Session::Cookie"; |
78 | |
79 | =head1 DESCRIPTION |
80 | |
81 | This middleware component allows you to use the cookie as a sole |
82 | cookie state and store, without any server side storage to do the |
83 | session management. This middleware utilizes its own state and store |
84 | automatically for you, so you can't override the objects. |
85 | |
86 | =head1 CONFIGURATIONS |
87 | |
88 | This middleware is a subclass of L<Plack::Middleware::Session> and |
89 | accepts most configuration of the parent class. In addition, following |
90 | options are accepted. |
91 | |
92 | =over 4 |
93 | |
94 | =item secret |
95 | |
96 | Server side secret to sign the session data using HMAC SHA1. Defaults |
97 | to nothing (i.e. do not sign) but B<strongly recommended> to set your |
98 | own secret string. |
99 | |
09db0676 |
100 | =item session_key, domain, expires, path, secure, httponly |
d326e755 |
101 | |
c4b2fb0e |
102 | Accessors for the cookie attributes. See |
d326e755 |
103 | L<Plack::Session::State::Cookie> for these options. |
104 | |
105 | =back |
106 | |
107 | =head1 AUTHOR |
108 | |
109 | Tatsuhiko Miyagawa |
110 | |
111 | =head1 SEE ALSO |
112 | |
113 | Rack::Session::Cookie L<Dancer::Session::Cookie> |
114 | |
115 | =cut |
116 | |