1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package File::Session;
use 5.006000;
use strict;
use warnings;
use Cache::FileCache;
use CGI;
use Digest::SHA ('sha256_hex');
our @ISA = qw(Cache::FileCache CGI);
our $VERSION = '0.04';
sub new {
my $class = shift;
$class->SUPER::new(@_);
}
sub retrieve_session {
my ($self) = @_;
my $session_id = $self->cookie('session_id');
if ($session_id) {
# Cookie vorhanden
# Set the ID
$self->id($session_id);
return $session_id;
}
else {
# kein Cookie vorhanden? Dann mach eines!
my $cookie = $self->cookie(-name => 'session_id',
-value => $self->generate_id() );
print $self->redirect(-cookie => $cookie, -uri => $self->self_url());
}
}
sub generate_id {
my ($self) = @_;
my $len = 24;
my @session_chars = ('A' .. 'Z', 'a' .. 'z', 0 .. 9, '.', '-');
my $id;
eval {
open(RANDOM, "/dev/urandom") or die $!;
read(RANDOM, $id, $len) == $len;
close RANDOM;
$id =~ s/(.)/$session_chars[ord($1) & 63]/esg;
$id .= time() . $$;
$id = sha256_hex($id);
return $id;
};
if ($@) {
# if random is not avaible, create the SID as in CGI::Session
# thanks for the inspiration ;-)
my $sha = Digest::SHA->new(256);
$sha->add($$ , time() , rand(time) );
$id = $sha->hexdigest();
}
return $id;
}
sub id {
my ($self, $new_id) = @_;
my $old_id = $self->{'id'};
$self->{'id'} = $new_id if ($new_id);
return $old_id;
}
sub get_data {
my ($self) = @_;
my $session_id = $self->id();
my $data = $self->get($session_id);
$self->set($session_id,$data);
return $data;
}
1;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Create File::Session Object
my $session = File::Session->new({'namespace'=>'sessions',
'cache_root'=>"$DATADIR/cache",
'default_expires_in' => '900s',
'cache_depth' => '0'});
# Retrieve the session_id if there is still a session_cookie
# or if not create a cookie and redirect
my $session_id = $session->retrieve_session;
[...]
sub login {
# Wie gehabt. Nur muss der Login Status wie folgt gespeichert werden
# hier muss ich die set Funktion in jedem Fall noch überschreiben
$session->set($session_id, {"login" => "can_access"});
}
[...]
# Der Login Status wird wie folgt ausgelesen (zugleich wird die Zeit
# bis zum automatischen Logout durch die get_data Funktion hochgesetzt)
my $session_data = $session->get_data;
my $login = $session_data->{'login'} || undef;