add files
|
1 |
package Mojolicious::Sessions; |
2 |
use Mojo::Base -base; |
|
3 | ||
4 |
use Mojo::JSON; |
|
5 |
use Mojo::Util qw(b64_decode b64_encode); |
|
6 | ||
7 |
has [qw(cookie_domain secure)]; |
|
8 |
has cookie_name => 'mojolicious'; |
|
9 |
has cookie_path => '/'; |
|
10 |
has default_expiration => 3600; |
|
11 | ||
12 |
sub load { |
|
13 |
my ($self, $c) = @_; |
|
14 | ||
15 |
return unless my $value = $c->signed_cookie($self->cookie_name); |
|
16 |
$value =~ s/-/=/g; |
|
17 |
return unless my $session = Mojo::JSON->new->decode(b64_decode $value); |
|
18 | ||
19 |
# "expiration" value is inherited |
|
20 |
my $expiration = $session->{expiration} // $self->default_expiration; |
|
21 |
return if !(my $expires = delete $session->{expires}) && $expiration; |
|
22 |
return if defined $expires && $expires <= time; |
|
23 | ||
24 |
my $stash = $c->stash; |
|
25 |
return unless $stash->{'mojo.active_session'} = keys %$session; |
|
26 |
$stash->{'mojo.session'} = $session; |
|
27 |
$session->{flash} = delete $session->{new_flash} if $session->{new_flash}; |
|
28 |
} |
|
29 | ||
30 |
sub store { |
|
31 |
my ($self, $c) = @_; |
|
32 | ||
33 |
# Make sure session was active |
|
34 |
my $stash = $c->stash; |
|
35 |
return unless my $session = $stash->{'mojo.session'}; |
|
36 |
return unless keys %$session || $stash->{'mojo.active_session'}; |
|
37 | ||
38 |
# Don't reset flash for static files |
|
39 |
my $old = delete $session->{flash}; |
|
40 |
@{$session->{new_flash}}{keys %$old} = values %$old |
|
41 |
if $stash->{'mojo.static'}; |
|
42 |
delete $session->{new_flash} unless keys %{$session->{new_flash}}; |
|
43 | ||
44 |
# Generate "expires" value from "expiration" if necessary |
|
45 |
my $expiration = $session->{expiration} // $self->default_expiration; |
|
46 |
my $default = delete $session->{expires}; |
|
47 |
$session->{expires} = $default || time + $expiration |
|
48 |
if $expiration || $default; |
|
49 | ||
50 |
my $value = b64_encode(Mojo::JSON->new->encode($session), ''); |
|
51 |
$value =~ s/=/-/g; |
|
52 |
my $options = { |
|
53 |
domain => $self->cookie_domain, |
|
54 |
expires => $session->{expires}, |
|
55 |
httponly => 1, |
|
56 |
path => $self->cookie_path, |
|
57 |
secure => $self->secure |
|
58 |
}; |
|
59 |
$c->signed_cookie($self->cookie_name, $value, $options); |
|
60 |
} |
|
61 | ||
62 |
1; |
|
63 | ||
64 |
=encoding utf8 |
|
65 | ||
66 |
=head1 NAME |
|
67 | ||
68 |
Mojolicious::Sessions - Signed cookie based session manager |
|
69 | ||
70 |
=head1 SYNOPSIS |
|
71 | ||
72 |
use Mojolicious::Sessions; |
|
73 | ||
74 |
my $sessions = Mojolicious::Sessions->new; |
|
75 |
$sessions->cookie_name('myapp'); |
|
76 |
$sessions->default_expiration(86400); |
|
77 | ||
78 |
=head1 DESCRIPTION |
|
79 | ||
80 |
L<Mojolicious::Sessions> manages simple signed cookie based sessions for |
|
81 |
L<Mojolicious>. All data gets serialized with L<Mojo::JSON> and stored |
|
82 |
C<Base64> encoded on the client-side, but is protected from unwanted changes |
|
83 |
with a C<HMAC-SHA1> signature. |
|
84 | ||
85 |
=head1 ATTRIBUTES |
|
86 | ||
87 |
L<Mojolicious::Sessions> implements the following attributes. |
|
88 | ||
89 |
=head2 cookie_domain |
|
90 | ||
91 |
my $domain = $sessions->cookie_domain; |
|
92 |
$sessions = $sessions->cookie_domain('.example.com'); |
|
93 | ||
94 |
Domain for session cookies, not defined by default. |
|
95 | ||
96 |
=head2 cookie_name |
|
97 | ||
98 |
my $name = $sessions->cookie_name; |
|
99 |
$sessions = $sessions->cookie_name('session'); |
|
100 | ||
101 |
Name for session cookies, defaults to C<mojolicious>. |
|
102 | ||
103 |
=head2 cookie_path |
|
104 | ||
105 |
my $path = $sessions->cookie_path; |
|
106 |
$sessions = $sessions->cookie_path('/foo'); |
|
107 | ||
108 |
Path for session cookies, defaults to C</>. |
|
109 | ||
110 |
=head2 default_expiration |
|
111 | ||
112 |
my $time = $sessions->default_expiration; |
|
113 |
$sessions = $sessions->default_expiration(3600); |
|
114 | ||
115 |
Default time for sessions to expire in seconds from now, defaults to C<3600>. |
|
116 |
The expiration timeout gets refreshed for every request. Setting the value to |
|
117 |
C<0> will allow sessions to persist until the browser window is closed, this |
|
118 |
can have security implications though. For more control you can also use the |
|
119 |
C<expiration> and C<expires> session values. |
|
120 | ||
121 |
# Expiration date in seconds from now (persists between requests) |
|
122 |
$c->session(expiration => 604800); |
|
123 | ||
124 |
# Expiration date as absolute epoch time (only valid for one request) |
|
125 |
$c->session(expires => time + 604800); |
|
126 | ||
127 |
# Delete whole session by setting an expiration date in the past |
|
128 |
$c->session(expires => 1); |
|
129 | ||
130 |
=head2 secure |
|
131 | ||
132 |
my $bool = $sessions->secure; |
|
133 |
$sessions = $sessions->secure($bool); |
|
134 | ||
135 |
Set the secure flag on all session cookies, so that browsers send them only |
|
136 |
over HTTPS connections. |
|
137 | ||
138 |
=head1 METHODS |
|
139 | ||
140 |
L<Mojolicious::Sessions> inherits all methods from L<Mojo::Base> and |
|
141 |
implements the following new ones. |
|
142 | ||
143 |
=head2 load |
|
144 | ||
145 |
$sessions->load(Mojolicious::Controller->new); |
|
146 | ||
147 |
Load session data from signed cookie. |
|
148 | ||
149 |
=head2 store |
|
150 | ||
151 |
$sessions->store(Mojolicious::Controller->new); |
|
152 | ||
153 |
Store session data in signed cookie. |
|
154 | ||
155 |
=head1 SEE ALSO |
|
156 | ||
157 |
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>. |
|
158 | ||
159 |
=cut |