> I did something like this. But, I ended up getting rid of cgi::session and
> writing my own little session manager. For a few reasons. I felt
> cgi::session provided more than I needed. And, if I did my own I could do
> some things peculiar to my own requirements.
>
> One thing I do is store the page the user was last at. For example, if the
> user goes to a lookup page, and the cgi_prerun determines the user is not
> logged in (new visit or login expired due to inactivity?) it will
> create the
> session, set the "last at" value and then set the header to
> redirect to the
> login page using https. cgi_prerun sets the run_mode to a mode which emits
> nothing (so the header kicks in without any page being sent to
> the browser.
> At the login script, it does the login and then, if the "last at" value of
> the session is set, it redirects back to that page (without
> https). If it's
> not set (maybe the user came directly to the login), it just redirects to
> main page (without https).
>
> It works pretty good. Every instance script has the same logic in the
> cgi_prerun. They each have the same teardown method to update the session
> automatically when the instance ends. If I could figure out how to do a
> superclass, I suppose I could put all this into one superclass and inherit
> it across all the instance scripts.
>
> I created my session tool to be an object and store stuff in MySQL. It's
> specific to my use. But, if you want it I'd be happy to give it
> to you. You
> could define your session table and then change all the SQL to
> reflect your
> table.
>
> Mark
>
Mark,
It sounds like you've mostly done what I want to do. Could you elaborate on
this part ...
> login page using https. cgi_prerun sets the run_mode to a mode which emits
> nothing (so the header kicks in without any page being sent to
> the browser.
... or maybe provide a code snippet.
I think I'm getting hung up on the redirect portion. I'm not sure exactly
how to code that. At first I thought, OK ... if my run_mode is 'login' then
redirect to https://mysite/mywebapp.cgi but then it just got stuck in a loop
because my run_mode was still 'login' after the redirect. Duh!!! So then I
started thinking about a multi-phase login and my brain cramped up. Or maybe
just a simple flag that says "we're on https so don't redirect". Would that
be too simple or should I continue over thinking this?
The code below is *sort of* working for a different project (using object
super class) without https. It uses CGI::Session and two different web app
cgi's: a login takes you to an admin cgi and logout takes you back to the
user cgi (both are based on the super class). It tries to be smart and
remember the last page but it doesn't always work and I haven't bothered to
fix it yet.
For my new project, I'd like to do this all with just one cgi. If the user
has no session, all run_modes lead to https://mywebapp.cgi&rm=login and he
must login at. Then after https login the user is redirected back to
http://mywebapp.cgi&rm=default where default could be some default run_mode
or the run_mode that the user originally requested.
Here's a piece of my life ...
sub login_init {
my $self = shift;
# Get CGI query object
my $q = $self->query();
my $session = $self->session;
if ( $session->param("~logged-in") ) {
$self->user($session->param("~user"));
$self->passwd($session->param("~passwd"));
return 1;
}
my $user = $q->param("user") or return;
my $passwd = $q->param("passwd") or return;
if (my $profile = $self->load_profile($user,$passwd) ) {
$session->param("~profile",$profile);
$session->param("~logged-in",1);
$session->param("~user",$user);
$session->param("~passwd",$passwd);
$session->clear(["~login-trials"]);
$self->user($user);
$self->passwd($passwd);
return 1;
}
debug "no profile or bad user/password";
my $trials = $session->param("~login-trials") || 0;
return $session->param("~login-trials",++$trials);
}
sub load_profile {
my $self = shift;
my ($user, $passwd) = @_;
local $/ = "\n";
my $tempest = $self->tempest; # this tempest system account
#debug "load_profile:
tempest/user/passwd=",$tempest,"/",$user,"/",$passwd;
# first check the the user has a mysql acount
my $user_priv = $self->mysql_dbh->selectrow_hashref(qq/
SELECT *, PASSWORD('$passwd') AS given
FROM user
WHERE User = '$user'
/);
# then check that the user has a tempest account for this tempest system
account
if($user_priv->{given} eq $user_priv->{password}) {
#debug "password match";
my $user_profile = $self->tempest_dbh->selectrow_hashref(qq/
SELECT *
FROM users
WHERE user = '$user'
AND db = '$tempest'
/);
return $user_profile;
}
debug "no password match";
return undef;
}
sub cgiapp_prerun {
my $self = shift;
my $mode = shift;
# Get CGI query object
my $q = $self->query();
if($self->level eq 'admin') {
CGI::Session->name("TEMPEST_SID");
$self->session(new CGI::Session(undef, $q, {Directory=>"session"}));
unless ($mode eq 'logout') {
$self->login_init;
unless ($self->session->param("~logged-in")) {
debug "not logged in";
if ($self->session->param("~login-trials") >= 3) {
$self->error_message("<h2>You failed to login 3 consecutive
times!!</h2><br>" .
"You SportsTempest Administrative session
is Blocked :(<br>" .
"Please contact us to reset your
password");
debug $self->error_message;
$self->set_page_content('error');
$self->prerun_mode('error');
return;
}
else {
$self->set_page_content('login');
$self->prerun_mode('login');
return;
}
}
# WE NEED TO DO THIS SELECTIVLY; WE DON'T WANT TO RETURN TO ONE OF
THE SUB-EDIT PAGES
# go back to previous last used run mode when starting
if ($mode eq 'start') {
my $last_mode = $self->session->param("~last-mode");
if (defined $last_mode) {
$mode = $last_mode;
}
else {
$mode = 'setup';
}
$self->prerun_mode($mode);
}
else {
$self->session->param("~last-mode",$mode)
}
}
}
$self->set_page_content($mode);
#
# it's ok if scope_id is undefined; we'll work with a default
#
#
my $scope_id = $q->param("select_scope_id");
$scope_id = $q->param("scope_id") unless defined $scope_id;
}
sub cgiapp_postrun {
my $self = shift;
my $output_ref = shift;
# Get CGI query object
my $q = $self->query();
#debug "testme = $TESTME";
my $run_mode = $self->get_current_runmode();
$self->menu_template->param(LOOP_MENU => $self->menu,
MENU_NAME => $self->menu_name);
my $menu = $self->menu_template->output;
if(defined ($self->session) ) {
my $cookie = $q->cookie(TEMPEST_SID =>
$self->session->id,'','',0,'+1h');
$self->header_props(-cookie=>$cookie);
}
if($run_mode eq 'logout') {
$self->header_type('redirect');
$self->header_props(-url=>"tempest.cgi");
}
my $tempest = $self->tempest;
push @{$JSCRIPTS{$run_mode}}, ({-language =>
'JavaScript',-src=>'/javascript/tempest.js'});
my $code = $self->init;
if($code) {
push @{$JSCRIPTS{$run_mode}}, ({-language =>
'JavaScript',-code=>$code});
}
$code = $self->inline;
if($code) {
push @{$JSCRIPTS{$run_mode}}, ({-language =>
'JavaScript',-code=>$code});
}
my $start = $q->start_html(-title=>'Sports Tempest User',
-author=>'suppressed',
-topmargin=>0,
-style=>{-src=>'/style/style.css'},
-script=>$JSCRIPTS{$run_mode},
-noscript=>"<h1>You need to enable JavaScript
to use this site</h1>",
-onload=>$self->onload,
-BGCOLOR=>$self->site_content->{bg_color}{val
ue});
my $page_title = defined($self->page_content->{page_title}) ?
$self->page_content->{page_title}:
$self->page_content->{description};
$self->base_template->param(USER_TITLE1 =>
$self->site_content->{title1}{value},
USER_TITLE2 =>
$self->site_content->{title2}{value},
USER_TITLE3 =>
$self->site_content->{title3}{value},
CONT_HEADER => $page_title,
CONT_ALIGN =>
$self->page_content->{page_align},
MENU_TEMPEST => $menu,
START => $start,
CONTENT => $$output_ref);
$$output_ref = $self->base_template->output;
}
and the instance script in the admin cgi ...
sub show_login {
my $self = shift;
# Get CGI query object
my $q = $self->query();
my $template = $self->load_tmpl('admin_login.tmpl', loop_context_vars =>
1, associate=>$self->session);
return $template->output;
}
sub logout {
my $self = shift;
$self->session->clear(["~logged-in"]) if defined $self->session;
return "You have logged out";
}
---------------------------------------------------------------------
Web Archive: http://www.mail-archive.com/suppressed/
http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: suppressed
For additional commands, e-mail: suppressed
Mail converted by mhonarc 2.6.15
This archive provided courtesy of JSW4.NET, Internet Hosting Services for Small Business.