Silly Newbie Question: cookies and such

2001-11-12 Thread Jon Robison

Unfortunatly, I find myself with a silly newbie question:

I need to make an Apache module (not a Registry script) which will:

1. Check for a cookie, and if not there, pushhandler to a module for
logging in (keeping the original request at hand for use after they
succeed in logging in).
2. Extract data from the cookie (encrypted for security?)
3. Based on data from both the query string ($r-args?) and from data in
the cookie, pushhandler to another module.

I have looked at Apache::AuthCookie - it didn't seem to make much sense
to me.  Apache::Session looks promising, but the instructions don't say
how to set up the mysql tables, etc. My worst problem is that I haven't
had occasion to deal with cookies much (setting, checking,etc.) in the
past and I know this is hampering my understanding.

Can anyone give me a general overview (use this module, this way, etc.)?

I'm not totally new to Apache Modules, but my experience is gleaned from
writing modules already pushed into the handler stack by
PerlTransHandlers written by someone else. I don't want to use
PerlTransHandler, just PerlHandler, so I can use Location in
perl.conf.

In conclusion: I'm making a system/site where no .html files even exist.
I need to handle security via a mysql db, and to push handlers based on
a part of the url and a piece of the cookie which identifies the user as
either a teacher, student, or parent (oops... I gave it away ;-)

Jonathon Robison



Re: Silly Newbie Question: cookies and such

2001-11-12 Thread Cees Hek

On Tue, 13 Nov 2001 04:28, you wrote:
 I need to make an Apache module (not a Registry script) which will:

 1. Check for a cookie, and if not there, pushhandler to a module for
 logging in (keeping the original request at hand for use after they
 succeed in logging in).
 2. Extract data from the cookie (encrypted for security?)
 3. Based on data from both the query string ($r-args?) and from data in
 the cookie, pushhandler to another module.

 I have looked at Apache::AuthCookie - it didn't seem to make much sense
 to me.  Apache::Session looks promising, but the instructions don't say
 how to set up the mysql tables, etc. My worst problem is that I haven't
 had occasion to deal with cookies much (setting, checking,etc.) in the
 past and I know this is hampering my understanding.

You should definately be using Auth::Cookie for this.  I would give the docs 
another read.  It took me a couple of tries to get it working successfully, 
but I have implemented it in about 4 or 5 applications, and it works 
flawlessly.

With Auth::Cookie it will handle the cookies for you, it will do the 
redirection to your login page for you, and it can handle logouts as well (by 
expiring the cookie).

As for Apache::Session, it is really just a keyed data store with expiry 
times.  You give it some data, and it gives you a key.  If you come back 
later and give it the same key, it gives you back your data.

A lot of people use Auth::Cookie and Apache::Session together to build a 
session management system, but I prefer just using a ticket based system with 
Auth::Cookie alone (See the Eagle book on how to do ticket based 
authentication).  I have included a sample Auth::Cookie implementation that 
might give you some ideas.  It is not complete, but it might get you going (I 
have stripped out some of the irrelevant code, so it probably won't work out 
of the box).  Also you will have to provide your own login.pl and logout.pl 
scripts (I would use the examples that come with Auth::Cookie until you get a 
working system, then you can look at building your own.

 In conclusion: I'm making a system/site where no .html files even exist.
 I need to handle security via a mysql db, and to push handlers based on
 a part of the url and a piece of the cookie which identifies the user as
 either a teacher, student, or parent (oops... I gave it away ;-)

After Auth::Cookie has finished it's phase, it will set the REMOTE_USER 
environment variable to the user that logged in.  You could just as easily 
set this to 'teacher' or whatever.  Then your content handler can look at 
this variable and decide what to do.  

HTH

Cees



package My::Auth::AuthCookie;

require 5.000;
use strict;
use Apache::AuthCookie;
use My::Crypt;

@My::Auth::AuthCookie::ISA = qw(Apache::AuthCookie);

#
##

# There are far more secure ways of handling the passphrase then keeping it in
# the actual code, but this is by far the easiest...
sub SECRET () { 'No one will ever guess this passphrase :)'; }

my $CRYPTER ||= new My::Crypt;  # This utility just uses the Crypt::CBC and
 # Storable modules to encrypt and decrypt perl
 # data structures. It also does an MD5 checksum

sub authen_cred ($$\@) {
my $self  = shift;
my $r = shift;
my @creds = @_;

#
# get the entered details
#
my $email= $creds[0];
my $password = $creds[1];

#
# ensure that the user is valid and authorized...
# right now it accepts any email and password combo,
# so obviously you would check this in a database or
# something
#
if ($email  $password) {
return $self-makeTicket($r, $email);
}
else {
return;
}
}

sub authen_ses_key ($$$) {
my $self   = shift;
my $r  = shift;
my $ticket = shift;

#
# verify the ticket (to make sure no-one has tampered with it and it hasn't 
expired etc...)
#
my ($result, $message) = $self-verifyTicket($r, $ticket);

#
# Check the result and act appropriately...
#
if (!$result) {
# $r-log-error(Browser returned bad cookie ($message));
return undef;
}
else {
#
# Make and set a new cookie (so that the 'time' in the cookie is 
updated 
and expires
# works as expected - since last access etc...)
#
my $new_ticket = $self-makeTicket($r, $message);
$self-send_cookie($new_ticket);

#
# Return the 'message/string' which will be set in the environment
# under REMOTE_USER (aka.. $ENV{REMOTE_USER}).  In our case that is
# the users email