Show Contents Previous Page Next Page
Chapter 5 - Maintaining State Other Server-Side Techniques In this section... Introduction Show Contents Go to Top Previous Page Next Page
Before we finish up this chapter, we touch on a couple of other techniques for storing state information on the server side of the connection.
Non-DBI Databases Show Contents Go to Top Previous Page Next Page Because of its portability, the DBI database interface is probably the right
choice for most server-side database applications. However, any database system
that was designed to support multiple write access will work for this application.
For example, the object-oriented ACEDB system that Lincoln works with is well
suited to applications that require complex, richly interlinked information
to be stored. The database is freeware; you can find out more about it at http://stein.cshl.org/AcePerl/.
You might be tempted to try to store session information using a Unix NDBM, GDBM, or DB_FILE database. If you try this, you may be in for an unpleasant surprise. These databases were designed for good multiuser read performance but not for transactions in which several processes are reading and writing simultaneously. They keep an in-memory cache of a portion of the database and don't immediately know when another process has updated a portion that's cached. As a result, the database can easily become corrupt if multiple Apache daemons open it for writing.
You can work around this problem by carefully locking the files, flushing after each write, and closing and reopening the file at strategic points, but believe us, it isn't worth it. Version 2 of the Berkeley DB library does support transactions, however, and Paul Marquess's experimental Berkeley_DB module provides an interface to it. We have not experimented with this database yet, but it looks like it might provide a lightweight solution for storing web session information in situations where a DBI database would be overkill.
Using Authentication to Provide Session IDs Show Contents Go to Top Previous Page Next Page
Because the techniques for storing state information on the server side all require some sort of session ID to be maintained by the browser, they share a drawback. Regardless of whether the session ID is stored in a cookie or inside the URI, it sticks to the browser, not to the user. When the reigning hangman champ moves from his home computer to his office computer, he loses access to his current score information. Of course you could instruct users to write down their session IDs and type them back into the URI or cookie file when they move to a new machine, but this is awkward and inconvenient. You could try to recover session IDs from usernames, but this makes it too easy for people to steal each other's sessions.
In some applications, it makes sense to give each user a unique username/password pair and ask users to log in to your application. You can then use the username as the session key and be guaranteed that no sessions will conflict. Users can't steal each others' sessions without guessing the password, which is sufficient security for most applications.
The simplest way to do this is to use Apache's built-in authentication modules for password-protecting your script's URI. When the user tries to access the script, he is presented with a dialog box prompting him for his username and password. Apache verifies the information he provides against a file of stored usernames and passwords and allows access to the script if the information checks out. Before calling your script, Apache places the username into the request object. If you are using Apache::Registry, this information can be recovered from the CGI environment variable $ENV{REMOTE_USER} . From within an Apache Perl module, you can recover the username from the connection object in this way:
$username = $r->connection->user;
With this technique we can write a concise replacement for the get_session_id() subroutine in the server-side hangman scripts:
sub get_session_id {
return $ENV{REMOTE_USER};
}
The Apache distribution comes with a variety of authentication modules that use text files or Unix DBM files as their password databases. These may be adequate for your needs, or you might want to integrate the database of usernames and passwords with the database you use to store session information. The next chapter shows you how to do this and much more.
Apache::Session Show Contents Go to Top Previous Page Next Page After this chapter was written, Jeffrey Baker released an Apache::Session
module that implements many of the techniques described in this chapter. This
module had undergone several revisions, including contributions from many mod_perl
developers that have stabilized and enhanced Apache::Session, making
it fit for a production environment across all platforms. We strongly recommend
taking a look at this module when considering application state management implementation.
Show Contents Go to Top Previous Page Next Page Copyright © 1999 by O'Reilly & Associates, Inc. |