Phoenix.pm: Keeping track of web logins

Joel Nelson joelnelson at home.net
Tue Aug 1 23:20:51 CDT 2000



Mike Cantrell wrote:

> I'm wondering if someone out there has a good method of keeping track of web
> logins when going from page to page. I've ofter relied on .htaccess to
> generate a $ENV{REMOTE} user to check against but what if you aren't using
> .htaccess and have a html based login form?
>
> 1) I've thought about setting temp cookies but that seems like a security
> problem and I'd rather not use cookies anyways.

You can still solve it somewhat that way.

> 2) creating hidden tags to pass along to the next page if it's a form but
> what if it's not a form? That also seems like a security problem.

Not a good idea.

> 3) encoding the login/passwd into the URL string but that seems to be a
> security problem as well. Has anyone tried encrypting the login/passwd in
> the URL string? Is there any good doc's out there on doing such a thing?

Same as the last one, no!

> 4) I often see long sessionID variables in URL strings of sites I've logged
> into but I'm not sure what they are doing with it.

That's sort of the .asp way. You could try Jim's suggestion and check out
Apache::Session. I have not tried it. However, I do have a cookie way that I
kinda like. I converted a method I found somewhere on the PHP site. Assuming
your using perl, it goes something like this:

We don't use the users password in the cookie at all for security reasons. After
they submit their name and password and it is verified against the database, we
use their login name encrypted with todays weekday name to create an encrypted
key stored as a cookie. Each time they access a page protected by the script, we
take the name and key from the cookies, create a new key based on todays
weekname and their login name, and compare the newly created key with the cookie
key. If they are the same we don't need to check the database and we reset the
cookies. Even as I type it, it sounds confusing, but it works okay. I pasted in
the code we use. You'll figure it out. Hope it helps!!

Joel

###########################################################
# _Login.inc                                              #
#                                                         #
# To be included in cgi scripts requiring member access.  #
# Exports: $memberSeq $memberName & $memberPassword       #
#                                                         #
###########################################################
use DBI;

#$byPassDbSecurity = 1;

#------------------------------- Start of Main program loop
---------------------------#
&_initialize;

if (%memberInfo) {
  #print header,start_html,"cookie
info:<br>name[$memberName]<br>key[$memberKey]",end_html; exit;
  if (&passesCookieSecurity) {
    &setCookieAndContinue;
  } else {
    &loginForm("Security Info changed, you must log in again!");
  }
} elsif ($loggingIn) {
  #print header,start_html,"logging
In:<br>name[$fMemberName]<br>key[$fMemberKey]",end_html; exit;
  if (&passesDbSecurity) {
    &setDbCookieAndContinue;
  } else {
    &loginForm("Login Error");
  }
} else { &loginForm() }

#-------------------------------- End of Main program loop
---------------------------#

#--------------------------------- Start of sub-routines
-----------------------------#

#<----------------------------------------------------------------------
initialize -->
sub _initialize {
  # Do we already have cookie info? If so, set member variables
  %memberInfo = cookie('memberInfo');
  if (%memberInfo) {
    $memberName = $memberInfo{'memberName'};
    $memberSeq  = $memberInfo{'memberSeq'};
    $memberKey  = $memberInfo{'memberKey'};
    $parentSeq  = $memberInfo{'parentSeq'};
  }
  %memberPrefs = cookie('memberPrefs');
  if (%memberPrefs) {
    $memberCompany = $memberPrefs{'memberCompany'};
    $memberType    = $memberPrefs{'memberType'};
  }

  # Do we have form variables? If so, we're logging in
  $fMemberName = param('fMemberName');
  $fMemberPassword  = param('fMemberPassword' );
  if ($fMemberName && $fMemberPassword) { $loggingIn = 1 }
  $fMemberCompany   = param('fMemberCompany');
  $fMemberCompany   = $memberCompany unless ($fMemberCompany);
  $fMemberType      = $memberType unless ($fMemberType);

  # Set general script variables
  $script = script_name unless $script;
}

#<----------------------------------------------------- passesCookieSecurity -->

sub passesCookieSecurity {
  my @days =
('sunday','monday','tuesday','wednesday','thursday','friday','saturday');
  my @time = localtime(time);
  my $cryptKey = $days[$time[6]];
  if ($memberKey eq crypt($memberName,$cryptKey)) { return 'true'; }
}

#<----------------------------------------------------- setCookieAndContinue -->

sub setCookieAndContinue {
  my $cookie =
cookie(-name=>'memberInfo',-value=>\%memberInfo,-expires=>'+8h',-path=>'/');
  my $cookie2 =
cookie(-name=>'memberPrefs',-value=>\%memberPrefs,-expires=>'+1y',-path=>'/');
  print header(-cookie=>[$cookie,$cookie2]);
}

#<--------------------------------------------------------- passesDbSecurity -->

sub passesDbSecurity {
  if ($byPassDbSecurity) { return 'true'; }
  else {
    $dbh = DBI->connect($dataSource,$dbUser,$dbPassword) || die("SQL Error:
".$dbh->errstr);

    # Is this login a company/agency?
    if ($fMemberType eq 'company') {
      $query = "select c.name,u.userSeq,u.companySeq,u.name,u.password from user
u, company c where c.companySeq = u.companySeq and u.name = '$fMemberName' and
c.name = '$fMemberCompany'";
    } else {
      $query = "select c.name,u.agentSeq,u.agencySeq,u.name,u.password from
agent u, agency c where c.agencySeq = u.agencySeq and u.name = '$fMemberName'
and c.name = '$fMemberCompany'";
    }

    my $sth = $dbh->prepare($query);
    $sth->execute;
    $errorMsg = $dbh->errstr();
    if ($errorMsg) { $error = "$errorMsg"; }
    else {
      my $numrows = $sth->rows;
      if ($numrows == 0) {
        $error = "Member [$fMemberName] name not found. Remember, name and
password are CaSe sensitive!";
      }
    }

    if (!$error) {
      my @row = $sth->fetchrow;
      if (lc($row[0]) ne lc($fMemberCompany)) {
        $error = "Invalid company for user [$fMemberName]!";
      }
      if ($row[4] ne $fMemberPassword) {
        $error = "Password incorrect for member [$fMemberName]. Remember, name
and password are CaSe sensitive!";
      }
      $memberSeq = $row[1];
      $parentSeq = $row[2];
    }

    if (!$error) { return 'true'; }
  }
}

#<--------------------------------------------------- setDbCookieAndContinue -->

sub setDbCookieAndContinue {
  my @days =
('sunday','monday','tuesday','wednesday','thursday','friday','saturday');
  my @time = localtime(time);
  my $cryptKey = $days[$time[6]];
  $memberInfo{'memberName'} = $fMemberName;
  $memberInfo{'memberSeq'} = $memberSeq;
  $memberInfo{'memberKey' } = crypt($fMemberName,$cryptKey);
  $memberInfo{'parentSeq' } = $parentSeq;
  my $cookie =
cookie(-name=>'memberInfo',-value=>\%memberInfo,-expires=>'+8h',-path=>'/');
  $memberPrefs{'memberCompany'} = $fMemberCompany;
  $memberPrefs{'memberType'} = $fMemberType;
  $memberType = $fMemberType;  # Needed for changing from one user type to
another
  my $cookie2 =
cookie(-name=>'memberPrefs',-value=>\%memberPrefs,-expires=>'+1y',-path=>'/');
  print header(-cookie=>[$cookie,$cookie2]);
}

#<------------------------------------------------------------------------ Show
Form -->
sub loginForm {
  #Delete existing cookie info
  my %memberInfo;
  $cookie =
cookie(-name=>'MemberInfo',-value=>\%memberInfo,-expires=>'-1h',-path=>'/');

  print
  header(-cookie=>$cookie),
  start_html(-link=>'cyan',-vlink=>'cyan'),"\n",
  "<center>\n",
  "<table border=0 bgcolor=#333366 cellpadding=5 cellspacing=0 width=80%>\n",
  "  <tr>\n",
  "    <td>\n",
  "      <center><font face=arial color=white><font size=+1>Our
Company</font><p>You have accessed a members only area. If you are\n",
  "      already a member you can login below. Membership is <b>FREE</b> and
takes only\n",
  "      a couple of minutes.<br><a href=/cgi-bin/connect/signup.cgi>Click
here</a> to sign up!<font></center>\n",
  "    <td>\n",
  "  </tr>\n",
  " </table>\n",
    "</center>\n",
    "  <center>\n";
    if ($error) { print "<br><font color=red>$error</font><br>\n"; }
    print start_form(-method=>'post',-action=>$script);
    if ((!$fMemberName)&&($fMemberPassword)) { print "<center>Oops, missing
Name! </center>\n",br; }
    if (($fMemberName)&&(!$fMemberPassword)) { print "<center>Oops, missing
Password!  </center>\n",br; }
    print
    "<table border=1 cellpadding=0 cellspacing=0 bgcolor=cccccc>\n",
    "  <tr><td>\n",
    "    <table>\n",
    "      <tr>\n",
    "        <td colspan=2 align=center><font face='arial'>" .
ucfirst($fMemberType) . " Login</td>\n",
    "      </tr>\n",
    "      <tr>\n",
    "        <td align=right><font face='arial' size=-1><NOBR><b>Member
Name:&nbsp;</NOBR><br></td>\n",
    "
<td>",textfield(-name=>fMemberName,-size=>30,-value=>$fMemberName),"<br></td>\n",

    "      </tr>\n",
    "      <tr>\n",
    "        <td align=right><font face='arial'
size=-1><b>Password:&nbsp;<br></b></font></td>\n",
    "
<td>",password_field(-name=>fMemberPassword,-size=>30,-value=>$fMemberPassword),"<br></td>\n",

    "      </tr>\n",
    "      <tr>\n",
    "        <td align=right><font face='arial' size=-1><NOBR><b>Company
Name:&nbsp;</NOBR><br></td>\n",
    "
<td>",textfield(-name=>fMemberCompany,-size=>30,-value=>$fMemberCompany),"<br></td>\n",

    "      </tr>\n",
    "      <tr>\n",
    "        <td colspan=2 align=right><input type='Submit' value='Log
In'><br></td>\n",
    "      </tr>\n",
    "    </table>\n",
    "  </tr></td>\n",
    "</table>\n",
    end_form,
    "  </center>\n",
    end_html;
    exit;
}





More information about the Phoenix-pm mailing list