Paste: Non-private session store
Author: | dmpk2k |
Mode: | perl |
Date: | Sun, 21 Jun 2009 22:43:40 |
Plain Text |
package Session;
use Modern::Perl;
use signatures;
require Mojo::Cookie::Response;
require JSON;
require Digest::SHA;
require Clone;
require Test::Deep;
require Compress::Zlib;
my $SESSION_NAME = 'session';
my $SESSION_HMAC_NAME = 'session_hmac';
my $SESSION_HMAC_KEY = '091u23npu0298u1emo2i12s';
our %session;
our %received_session;
sub load_session( $context ) {
%session = ();
%received_session = ();
my $cookie_ref = $context->req->cookies;
return if not $cookie_ref;
my %cookies = map { $_->name => $_->value } @$cookie_ref;
my $encoded_session = $cookies{ $SESSION_NAME };
my $expected_session_hmac = $cookies{ $SESSION_HMAC_NAME };
return if not $encoded_session;
my $compressed_session = MIME::Base64::decode( $encoded_session );
my $serialized_session = Compress::Zlib::memGunzip( $compressed_session );
my $actual_session_hmac = Digest::SHA::hmac_sha256_base64( $serialized_session, $SESSION_HMAC_KEY );
return if $actual_session_hmac ne $expected_session_hmac;
%session = %{ JSON::decode_json( $serialized_session ) };
%received_session = %{ Clone::clone( \%session ) };
}
sub save_session( $context ) {
return if Test::Deep::eq_deeply( \%session, \%received_session );
my $serialized_session = JSON::encode_json( \%session );
my $compressed_session = Compress::Zlib::memGzip( $serialized_session );
my $encoded_session = MIME::Base64::encode( $compressed_session, '' );
my $session_hmac = Digest::SHA::hmac_sha256_base64( $serialized_session, $SESSION_HMAC_KEY );
my $encoded_session_cookie = Mojo::Cookie::Response->new( name => $SESSION_NAME,
value => $encoded_session,
path => '/' );
my $session_hmac_cookie = Mojo::Cookie::Response->new( name => $SESSION_HMAC_NAME,
value => $session_hmac,
path => '/' );
$context->res->cookies( ( $encoded_session_cookie, $session_hmac_cookie ) );
}
1;
New Annotation