Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: How to remember who is logged in...

by pope (Friar)
on Sep 05, 2002 at 04:19 UTC ( [id://195290]=note: print w/replies, xml ) Need Help??


in reply to How to remember who is logged in...

Here is the code snippet I usually use, I hope it's not hard for you with PHP background to follow:
my %who = (); # tied hash my %c = fetch CGI::Cookie; # received session cookie my $sid; # session id my $sc; # session cookie to sent if (%c) { # check existence of cookie # print STDERR Dumper %c; if (exists $c{sid}) { # check existence of session id in cookie $sid = $c{sid}->value; # untaint: ($sid) = $sid =~ /(.+)/; } } if ($sid) { # attempt to retrieve user information from session id eval { tie %who, 'Apache::Session::File', $sid, { Directory => $session_dir, LockDirectory => $session_lock_dir, }; }; if ($@) { # can't revive session id, probably already garbage-collected $sc = create_cookie($sid, "expires"); undef $sid; } } # if login is submitted, tie a session and retrieve $sid if (param('login')) { my $uname = param('uname'); my $upass = param('upass'); my ($uinfo, $mesg) = $db->auth_user($uname, $upass); unless ($uinfo) { # failed authentication. do smth and exit. } else { # generate session and send cookie in header eval { tie %who, 'Apache::Session::File', undef, { Directory => $session_dir, LockDirectory => $session_lock_dir, }; }; if ($@) { die "Can't create session: $@"; } $sid = $who{_session_id}; # store anything valuable $who{name} = $uinfo->{name}; $who{gname} = $uinfo->{gname}; } } if (exists $who{name}) { # if (%who) doesn't work here! why? # a user is currently logged in. # do smth he/she is allowed to do } else { # user is not logged in }
I don't know the fundamental difference between Apache::Session and CGI::Session. Both looks quite similar, with an important difference that CGI::Session uses Data::Dumper which is a standard module for its data serialization. Apache::Session uses Storable which requires separate installation, and a C compiler (it has XS code).

Yesterday I had a bad time with Apache::Session which fails to store data and ended with warnings in error log such as this:

 (in cleanup) Can't call method "update" on an undefined value at
/usr/local/lib/perl5/site_perl/5.6.1/Apache/Session.pm line 508 during
global destruction.

 (in cleanup) Can't call method "close" on an undefined value at
/usr/local/lib/perl5/site_perl/5.6.1/Apache/Session/File.pm line 41
during global destruction.
The strange thing is this happens only with an application I'm currently working on, I have several other applications running Apache::Session without problem. The logic for sessions storing and retrieval is the same, and that is the same code snippet as above. After several hours wasted to locate the problem, I tried CGI::Session. The interface is quite similar to Apache::Session, so changes is quite minimal: s/Apache/CGI/. And.. the problem disappeared (!)

I just couldn't believe that this is a problem with Apache::Session which is already out there for a couple of years. But now I'm sure that CGI::Session is a very good alternative to Apache::Session.

Replies are listed 'Best First'.
Potential security hazard, be careful
by Anonymous Monk on Sep 05, 2002 at 15:07 UTC
    If you use any session manager that uses Data::Dumper like CGI::Session does, then remember that Data::Dumper is not writing out simple data and then reading it back in. Data::Dumper writes out Perl code that is evaluated when you de-serialize your data. That means that if anybody has an opportunity to mess with your data files while they are sitting on the file system then you have a huge potential security risk.

    If you use Data::Dumper, be absolutely certain that nobody has write access to the data files that should not. I really don't like to use Data::Dumper for anything in CGI, partly for that reason and partly because it's just slow. You might want to look at using FreezeThaw. It's pure Perl so it doesn't require anything special, but it writes and reads data blocks instead of Perl code.

      This can be avoided using the Safe module. Build the compartment to evaluate the Perl-code configuration using
      $compartment = new Safe; $compartment->permit_only(qw(:base_core :base_mem)); # very restrictiv +e $result = $compartment->reval($unsafe_code);
      and the evaluated code will not be able to do anything than build data structures. (See perldoc Opcode for a list of tags.)

      Makeshifts last the longest.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://195290]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2024-04-20 05:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found