6.4.2 Doing your own authentication - Page 7
July 3, 2002
As you probably know, many web sites have their own login pages, rather than using
the mechanism shown in the previous section. Why is that preferable? There are a
number of reasons to choose to do your own logins:
- Having your own login page means not relying on browsers to behave correctly.
Some browsers had bugs in the caching code for realm information which
would cause the browser to send an invalid user and password pair to the server
over and over (as the server kept sending back invalid authentication responses).
It also allows the application to bypass the cache if the developer wants to force
the user to log in.
- I mentioned previously that the standard mechanism is unfriendly to new users.
By using your own page, you can control what your users see, provide clear
instructions, and tell them what authenticating information you want. You
might also use a cookie to store the username and prompt only for the password.
I've seen sites that have a custom login page which offers an option to
store both username and password in a cookie, allowing the user to choose less
security and more convenience.
- Most browsers indicate when SSL is in use by displaying a lock icon. Letting the
user log in from a special page gives a visual reassurance that they are sending
their password securely. Alternatively, if you offer the page over both HTTP and
HTTPS you can warn users when they are using an insecure connection.
- A login page is one more chance to display announcements, important links,
and advertising.
The most obvious disadvantage of writing your own login page is that you have to do
the coding yourself, but that's not terribly difficult. The CGI input set includes the
password input, which behaves like a regular text input but doesn't echo back the
user's characters; and on most OSs Perl includes a crypt function which performs
quick one-way encryption. (You could store passwords in your database without
encrypting them, but then anyone with unrestricted access to the database could steal
user passwords, resulting in one of those high-profile cases mentioned at the start of
the chapter.)
Here is a very simple login procedure, from Login.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');
This is the usual opening code; parse the request, get the expected parameters. The
application needs to display a login form, but it needs to display it in more than one
case, so the form is built in a variable using Perl's here-doc syntax:
# The login form.
my $loginForm = <<ENDHTML;
<FORM METHOD="POST">
<TABLE>
<TR>
<TD>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>
</TABLE>
<INPUT TYPE="submit" VALUE="Log in">
</FORM>
ENDHTML
The syntax looks odd but it works well once you are used to it. Everything from the
line after the label (marked by <<) to the next line beginning with the label is stored
in the variable $loginForm (or passed to the print function in later examples). In
this case, the label is ENDHTML and the variable contains all those lines of HTML.
This syntax works anywhere that a quoted string would work. In fact, it behaves just
as double quotes, so that variables in the here-doc are interpolated as they are in a
double quoted string. We use that property to put the current value of $username
into the form. If the application is invoked more than once, the username will be preserved
(but the password will not). That's also why $username is initialized if the
parameter wasn't passed in, to avoid errors about use of uninitialized values.
The here-doc syntax can be used with other forms of quoting; see Perl's perldata
documentation for more information. Since web applications often print large blocks
of HTML, it is common to see this syntax in Perl CGI or mod_perl scripts. It's not
uncommon to use an HTML editor to create the HTML blocks and then cut and paste
them into the body of the script. In the next chapter we'll look at other ways to merge
Perl and HTML.
Meanwhile, back to the example. Note that the login form uses a password input
type (also named password). As you'll see if you run the example, the browser echoes
asterisks (or nothing) as the user types there. Also note that the form specifies
METHOD="POST". The default method is GET, which would pass the username and
password as part of the URL (and thus probably display them on the browser's URL
line and log them in the server's access log).
6.4 User Authentication - Page 6
Web Development with Apache and Perl
6.4.2 Doing your own authentication (Cont.) - Page 8
|