http://qs321.pair.com?node_id=72101

arashi has asked for the wisdom of the Perl Monks concerning the following question:

I'm new to Perl, and I was hoping to get some ideas on webpage logins using Perl. I want users to be able to log in to make changes to an online journal. My thought was that the login screen would pass the users name and password to some sort of user validation script, that would check the database online, and if they pass the check, it would write their username, IP, and login time into a log file. Every page after that would check the log file to see if that IP is valid to edit the page, and to see if they haven't timed out. Am I on the right track here? I'd really like to hear about what others have done in this situation.

Thanks in advance for your help!

Arashi

Replies are listed 'Best First'.
Re: (Zigster) Webpage Logins
by zigster (Hermit) on Apr 12, 2001 at 21:18 UTC
Re: Webpage Logins
by knobunc (Pilgrim) on Apr 12, 2001 at 22:17 UTC

    Beware using the IP address as a unique token for a session. Any users that go through a proxy will appear to come from the same IP. AOL users for instance rotate through a handful of IP addresses for each request.

    The other replies have hopefully pointed you in the right direction.

    Also, if you decide to store the information in a file make sure you lock it when updating and reading. Otherwise it will get corrupted at some point.

    Updated: I had a chance to look at how I had coded the login stuff on my pages here. The relevant bit is to use Apache::Session which gives me an ID that I then stuff into a cookie. The IDs generated are relatively secure, they use all sorts of good random info then run it through an MD5 hash so I think they are unguessable. Anyway, onto the code:

    use Apache::Session::File; use CGI::Cookie; use constant TIMEOUT => 60 * 60 * 2; # 2 hours use constant COOKIE_NAME => 'MY_COOKIE'; use constant BASE_URL => '/'; # Get the ID from the cookie (if one was set) my $raw_cookie = $r->header_in('Cookie') || ""; my %cookies = parse CGI::Cookie($cookie); my $id = $cookies{COOKIE_NAME}; # Get the session object from disk my %session; tie %session, 'Apache::Session::File, $id, { Directory => '/tmp/state', LockDirectory => '/tmp/state', }; # Set the cookie back if it was new if (not defined $id) { my $new_cookie = new CGI::Cookie(-name => COOKIE_NAME, -value => $session->{_session_id}, -path => BASE_URL, ); $r->err_header_out('Set-Cookie' => $new_cookie); } # Now just read and write things to the session object # and they will get saved. You have to be careful about # any references though. See the docs for details. # Check to make sure the session is valid my $cur_time = time; unless (defined $session{last_access} and $session{last_access} < time - TIMEOUT and defined $session{valid} and $session{valid} == 1) { # Illegal access, bump to the login page # It must make the session valid by setting the # last_access and valid fields. } $session{last_access} = $cur_time;

    Please note that this code will probably need to be changed to fit your web environment. I was using $r since my code comes from mod_perl. If you are using straight CGI then there is a CGI.pm thing to set the cookie stuff in the response header. The above may or may not work since I cut and pasted relevant bits from my setup (I am using Mason) and actually have stuff split up across subroutines because my data store and autentication is a bit more twisty.

    -ben

Re: Webpage Logins
by dws (Chancellor) on Apr 12, 2001 at 22:44 UTC
    In the current issue of Web Techniques, merlyn has a good article on using cookies to manage login sessions. His approach is to "brand" the browser with a unique ID, and then manage login/logout + session state on the server side, using the branding as a lookup key into a disk cache of info. This approach avoids all of the problems related to trying to use the browser's reported IP address.

      Thanks for the reference to my column. But if you'd please refer to my archive rather than the one at the WT site, you'll help people get text with better jokes and downloadable code that actually works, instead of the frequent mis-steps that they seem to put on their site.

      -- Randal L. Schwartz, Perl hacker

Re: Webpage Logins
by nysus (Parson) on Apr 12, 2001 at 23:29 UTC
    I'm new to Perl as well and just finished writing a similar kind of script. My script asks for the password and merely passes it back to the same script and checks it against an unencoded password file. All subsequent browser/server transactions place the password into a hidden field to maintain user session continuity.

    Is this lock tight security? Absolutely not. But my point here is not so much to offer you a solution, but to remind you that there's no need buying a $2000 alarm system for your Ford Pinto, right? Most likely, no one will trouble themselves trying to capture my password with a packet sniffer. Even if they did, they couldn't cause any significant damage because my data just isn't that valuable and its no problem replacing it with my backup files. I know there are some purists out there who would disagree but they are probably security experts and have an agenda of paranoia to push. :-)

    As far as specific advice for your script, I would say be careful of using IP addresses as a way to verify a user. AOL user's IP addresses can change from page to page.

Re: Webpage Logins
by suaveant (Parson) on Apr 12, 2001 at 21:19 UTC
    More common is to set a cookie or something similar with a unique code you generate when they log in and compare against your log... maybe even have it change every once in a while or every page, depending on your wish for secure-ness. Also good to expire the code after a certain amount of non-use...

    of course, your way would work in most cases. Except for many users behind a firewall showing the same ip, maybe... it would work, but it's not the preferred way.
                    - Ant

Re: Webpage Logins
by michellem (Friar) on Apr 13, 2001 at 01:22 UTC
    You've already gotten some great advice and suggestions. My only addition would be the use of a database to keep track of users and passwords. If you set up a database, it's easy to set up a cgi script for adding users, changing passwords, etc. Also, you can keep track of info on users that way, and it's a bit more secure than an unencrypted text file.