use 5.008001;
use strict;
use warnings;
package Dancer2::Session::Cookie;
# ABSTRACT: Dancer 2 session storage in secure cookies
our $VERSION = '0.005'; # VERSION
use Session::Storage::Secure 0.007 ();
use Moo;
use Dancer2::Core::Types;
#--------------------------------------------------------------------------#
# Attributes
#--------------------------------------------------------------------------#
has secret_key => (
is => 'ro',
isa => Str,
required => 1,
);
has default_duration => (
is => 'ro',
isa => Int,
predicate => 1,
);
has _store => (
is => 'lazy',
isa => InstanceOf ['Session::Storage::Secure'],
handles => {
'_freeze' => 'encode',
'_retrieve' => 'decode',
},
);
sub _build__store {
my ($self) = @_;
my %args = ( secret_key => $self->secret_key );
$args{default_duration} = $self->default_duration
if $self->has_default_duration;
return Session::Storage::Secure->new(%args);
}
with 'Dancer2::Core::Role::SessionFactory';
#--------------------------------------------------------------------------#
# Modified SessionFactory methods
#--------------------------------------------------------------------------#
# We don't need to generate an ID. We'll set it during cookie generation
sub generate_id { '' }
# Cookie generation: serialize the session data into the session ID
# right before the cookie is generated
before 'cookie' => sub {
my ( $self, %params ) = @_;
my $session = $params{session};
return unless ref $session && $session->isa("Dancer2::Core::Session");
$session->id( $self->_freeze( $session->data, $session->expires ) );
};
#--------------------------------------------------------------------------#
# SessionFactory implementation methods
#--------------------------------------------------------------------------#
# _retrieve handled by _store
# We don't actually flush data; instead we modify cookie generation
sub _flush { return }
# We have nothing to destroy, either; cookie expiration is all that matters
sub _destroy { return }
# There is no way to know about existing sessions when cookies
# are used as the store, so we lie and return an empty list.
sub _sessions { return [] }
1;
# vim: ts=4 sts=4 sw=4 et:
__END__
=pod
=encoding utf-8
=head1 NAME
Dancer2::Session::Cookie - Dancer 2 session storage in secure cookies
=head1 VERSION
version 0.005
=head1 SYNOPSIS
# In Dancer 2 config.yml file
session: Cookie
engines:
session:
Cookie:
secret_key: your secret passphrase
default_duration: 604800
=head1 DESCRIPTION
This module implements a session factory for Dancer 2 that stores session state
within a browser cookie. Features include:
=over 4
=item *
Data serialization and compression using L<Sereal>
=item *
Data encryption using AES with a unique derived key per cookie
=item *
Enforced expiration timestamp (independent of cookie expiration)
=item *
Cookie integrity protected with a message authentication code (MAC)
=back
See L<Session::Storage::Secure> for implementation details and important
security caveats.
=head1 ATTRIBUTES
=head2 secret_key (required)
This is used to secure the cookies. Encryption keys and message authentication
keys are derived from this using one-way functions. Changing it will
invalidate all sessions.
=head2 default_duration
Number of seconds for which the session may be considered valid. If
C<cookie_duration> is not set, this is used instead to expire the session after
a period of time, regardless of the length of the browser session. It is
unset by default, meaning that sessions expiration is not capped.
=for Pod::Coverage method_names_here
generate_id
=head1 SEE ALSO
CPAN modules providing cookie session storage (possibly for other frameworks):
=over 4
=item *
L<Dancer::Session::Cookie> -- Dancer 1 equivalent to this module
=item *
L<Catalyst::Plugin::CookiedSession> -- encryption only
=item *
L<HTTP::CryptoCookie> -- encryption only
=item *
L<Mojolicious::Sessions> -- MAC only
=item *
L<Plack::Middleware::Session::Cookie> -- MAC only
=item *
L<Plack::Middleware::Session::SerializedCookie> -- really just a framework and you provide the guts with callbacks
=back
=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
=head1 SUPPORT
=head2 Bugs / Feature Requests
Please report any bugs or feature requests through the issue tracker
at L<https://github.com/dagolden/dancer2-session-cookie/issues>.
You will be notified automatically of any progress on your issue.
=head2 Source Code
This is open source software. The code repository is available for
public review and contribution under the terms of the license.
L<https://github.com/dagolden/dancer2-session-cookie>
git clone git://github.com/dagolden/dancer2-session-cookie.git
=head1 AUTHOR
David Golden <dagolden@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2013 by David Golden.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004
=cut