Hi Bill,

It might be worth your while to have a look at CGI::Session::Auth.  This is a
fairly young module that is still in early development, but I started using it
this week with CGI::Session and it looks very good to me.  It will greatly
simplify the code you provided in your previous message.   I will give you a
quick bit of code that I am working on to get you going.


In my base module I have the following to handle authentication and session
management:

use CGI::Session ();
use CGI::Session::Auth ();

# Get the current session object
#  (object will be created once per request)
sub session {
  my $self = shift;

  if (!$self->{_session}) {
    # create CGI::Session object for session handling
    $self->{_session} = CGI::Session->new('driver:PostgreSQL', $self->query, 
                                          { Handle => $self->db });
  }
  return $self->{_session};
}

# Get the current auth object
#  (object will be created once per request)
sub auth {
  my $self = shift;

  if (!$self->{_auth}) {
    # create CGI::Session::Auth object for authentication
    $self->{_auth} = new CGI::Session::Auth({ CGI     => $self->query, 
                                              Session => $self->session
    });
  }
  return $self->{_auth};
}

sub cgiapp_prerun {
  my $self  = shift;
  my $query = $self->query();

  # Check to see if the user is trying to login
  $self->auth->authenticate();

  # send out the session cookie and test to make 
  # sure the user actually accepts cookies
  my $session = $self->session;
  my $session_cookie_name = $session->name;
  if ($query->param('cookie_test') && !$query->cookie($session_cookie_name)) {
    # We tried to send a cookie, but it was rejected by the user.
    $self->prerun_mode('no_cookies');
  } elsif (!$query->cookie($session_cookie_name)) {
    # There is no session cookie yet
    # So send out a cookie header and reload
    # the current page.  To make sure they accept cookies
    # send along a 'cookie_test' url parameter so that we know
    # that the cookie was sent and not accepted if it doesn't
    # appear on the next incoming request
    $self->header_add(-cookie => $self->auth->sessionCookie);
    $query->param(-name => 'cookie_test', -value => '1');
    my $url = $query->self_url;
    $self->redirect($url);
    $self->prerun_mode('redirect'); # dummy runmode for redirection
  } elsif ($query->cookie($session_cookie_name) ne $session->id) {
    # There is a session cookie, but it is invalid so send a new one
    $self->add_template_params(session_timed_out => 1);
    $self->header_add(-cookie => $self->auth->sessionCookie);
  }
}


# Here is a sample protected runmode
sub show_data {
  my $self = shift;

  # check if visitor has already logged in
  if (not $self->auth->loggedIn) {
    return $self->redirect('/login.cgi');
    # Or return $self->login_page(); if you have a global runmode for your login
  }

...

}


Now all you have to do is provide a login runmode that has a form with a
username and password field.  All the hard and messy stuff is handled by
CGI::Session and CGI::Session::Auth.  All you need to do is some cookie
management (or URL management if you want to deal with users that don't accept
cookies), and you need to check in your runmode whether the user was
successfully logged in.

This is not complete code, but it should get you a long way there...  Also, I
should reiterate that CGI::Session::Auth is still in the alpha stage, but so far
I am very happy with how it works.

Cheers,

Cees

---------------------------------------------------------------------
Web Archive:  http://www.mail-archive.com/[EMAIL PROTECTED]/
              http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to