Web Developer's Virtual Library: Encyclopedia of Web Design Tutorials, Articles and Discussions


WDVL Newsletter

Active Server Pages
JSP/Java Servlets
Microsoft SQL Server
Daily Backup
Dedicated Servers
Streaming Audio/Video
24-hour Support    

jobs.webdeveloper.com

Hiermenus


e-commerce
Partner With Us















Developer Channel
FlashKit.com
JavaScript.com
JavaScriptSource
Developer Jobs
ScriptSearch
StreamingMediaWorld
Web Developer's Journal
Web Developer's Virtual Library
WebDeveloper.com
Webreference
Web Hosts
XMLfiles.com

internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers


6.5 User Management - Page 10

July 12, 2002

If a site has user data, it probably needs user management: functions for creating new user accounts and modifying their information. A site can offer public registration, which allows anyone to create an account and access the site, or have private registration where the potential user fills in a form or sends a mail message to an administrator who then creates an account. Sites that use private registration might still have a web application to create accounts, although the application and other administrative functions would be protected from public use.

To fill out the login handler started earlier, we'll add a page for filling in user information and creating an account. This will also extend the Users table into something more useful and add goodies such as telling the user when the account was last used.

The code samples here are from CreateUser. pm:

sub handler {
  # Receive and parse the request.
  my $r = shift;
  my $q = Apache::Request->new($r);
  my $username = $q->param('username') || '';
  my $password = $q->param('password');
  my $name = $q->param('name') || '';
  my $email = $q->param('email') || ''; 

This is the standard beginning, checking for and initializing parameters. It also builds the entry form in a variable, using the parameter values:

    # The entry form.
    my $form = <<ENDHTML;
<FORM METHOD="POST">
  <TABLE>
    <TR>
      <TD>Desired username:</TD>
      <TD><INPUT TYPE="text" NAME="username"
        VALUE="$username" SIZE=10></TD>
    </TR>
    <TR>
      <TD>Password:</TD>
      <TD><INPUT TYPE="password" NAME="password" SIZE=20></TD>
    </TR>
    <TR>
      <TD>Your real name:</TD>
      <TD><INPUT TYPE="text" NAME="name"
        VALUE="$name" SIZE=30></TD>
    </TR>
    <TR>
      <TD>Your e-mail address:</TD>
      <TD><INPUT TYPE="text" NAME="email"
        VALUE="$email" SIZE=24></TD>
    </TR>
  </TABLE>
  <INPUT TYPE="submit" VALUE="Log in">
</FORM>
ENDHTML

The code carries forward the previous values (if any) of the username, name, and email fields, blanking the password (which isn't echoed anyway). You might recall from the examples in chapter 3 that CGI. pm held onto parameter values automatically (it calls them " sticky parameters" ). Coding your own HTML means having to take care of this yourself or it means not having to work around CGI. pm features, depending on whom you ask.

If your password creation form doesn't echo password inputs, you should probably require the user to type the password twice and verify that both inputs are the same before creating the account. Some registration systems create a random password for the user and email it to a requested address. In that case, ask for the address twice to help avoid typos.

  # Get all the required inputs
  unless ($username && $password) {
    my $title = $ENV{'HTTPS'} ?
      'Secure login form' : 'Insecure login form';
    $r->send_http_header('text/html');

      print <<ENDHTML;
<!DOCTYPE HTML PUBLIC>
<HTML>
  <HEAD><TITLE>$title</TITLE></HEAD>
  <BODY>
    <H2>Please fill in the following information:</H2>
    $form
  </BODY>
</HTML>
ENDHTML
      return OK;
    }

This section prints the form if the required fields, username and password in this case, haven't been filled in. A more complex application should give the user a clear indication of what is required.

Note that when we created the Users table we allowed nulls in the name and email fields. We also don't require them to be input here. In general, a field which is required on a form shouldn't allow nulls in a database and vice-versa.

The next section verifies that the username is unique:

    # Check for a unique username.
    my $dbh = DBI->connect('DBI:mysql:Info:localhost',
          'web','nouser');
    return error($r, "Can't connect to Info") unless $dbh;
    my ($try) = $dbh->selectrow_array
      ('SELECT password FROM Users WHERE username = ?',
      undef, $username);
    if ($try) {
      $r->send_http_header('text/html');
      print <<ENDHTML;
<!DOCTYPE HTML PUBLIC>
<HTML>
  <HEAD><TITLE>Already exists</TITLE></HEAD>
  <BODY>
    <H2>User $username already exists.</H2>
    $form
  </BODY>
</HTML>
ENDHTML
    return OK;
  }

The retrieval code is the same as that of the previous example, but in this case a successful SELECT means that the requested username is taken. It doesn't really matter what we select from the table, so long as we'll know if the record exists. If not, we can go on to add the record:

# Encrypt the password.
$password = createPassword($password);

# Write the user record.
$dbh->do('INSERT INTO Users VALUES (?,?,?,?)',
      undef, $username, $password, $name, $email)
  || return error($r, $dbh->errstr);

This uses the createPassword function shown earlier to encrypt the password and then store it in the database. DBI's convenient do function prepares and executes the given statement. Recall that the first argument after the statement is for attributes, and the rest are placeholder values. There's nothing left to do but confirm things with the user.

    # Tell the user that they're one of us now.
    $r->send_http_header('text/html');
    print <<ENDHTML;
<!DOCTYPE HTML PUBLIC>
<HTML>
  <HEAD><TITLE>Account created</TITLE></HEAD>
  <BODY>
    <H2>Account created.</H2>
    Welcome to our site.
  </BODY>
</HTML>
ENDHTML
    return OK;
  }

Add this handler to your configuration file and restart Apache as usual:

PerlModule Examples::CreateUser
<Location /create>
  SetHandler perl-script
  PerlHandler Examples::CreateUser
</Location>

Note that the handler is assigned to /create, the URL which was given in the previous login example.

Although the creation example is meant to tie in to the login example, it could also be used by sites with HTTP authentication. The Apache:: DBI module includes an authentication hook that validates users in a database using DBI. The creation form could be used to create the necessary record, and regular HTTP authentication takes over from there.

Application designers should bear in mind that users come to a site for content, not user management. If a user requests protected pages without logging in, give them the login page, then go directly to the requested content after the user is validated. HTTP authentication appears to do this automatically (though actually it is the browser's authentication cache that quietly identifies the user for each page); techniques for doing it yourself follow in the next section.

6.4.2 Doing your own authentication (Cont.) - Page 9
Web Development with Apache and Perl
6.6 Login Sessions - Page 11


Up to => Home / Authoring / Languages / Perl / Apache_Perl




Jupiter Online Media: internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and Jupiter Online Media

Jupitermedia Corporate Info


Legal Notices, Licensing, & Permissions, Privacy Policy.

Web Hosting | Newsletters | Tech Jobs | Shopping | E-mail Offers