Newer Older
159 lines | 4.439kb
add files
Yuki Kimoto authored on 2014-03-26
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