A Login Plug-in

The login plug-in is a login script written as a drop-in plug-in — something that can simply be dropped into a project. It is intended as a building block for configuration management systems. This overview begins with a brief presentation of design goals, then gives recipes for using the login plug-in, and finishes with points of interest regarding the implementation.

Before reading further, you may wish to view the login demo. And after reading the documentation, you may wish to download the complete zip archive.

Design Goals

Intended use. There may be multiple users of the login mechanism. Such users do not register themselves but are introduced to the system by a user with administrative privileges. This distinction implies the existence of user roles.

Convenience versus security. A user whose computer is in a physically secure area has the option of having his browser remember the password. If a user forgets his password, the system mails it to him.

Self containment. The fact that this is a drop-in plug-in implies that the plug-in itself creates and manages the user database. Of course, there must still be page-specific PHP code for pages that respond to whether a user is logged in.

Simplicity. There is no configuration file. The initial user account has user id "admin" and password "easy". The name of the landing page is assumed to be index.php. And the name of the login page is is login/index.php.

How to use the Login Mechanism

From the landing page, make your way to the login page by adding /login to the URL. Log in, returning yourself to the landing page; it will now have additional information. This additional information allows you to get to privileged pages that are available only to logged in users. The whole process is as pictured in the following diagram:

Login Process

The first use of the login mechanism is to set up user accounts and initial passwords via the initial admin user account and the identity management page.

How to implement the Login Plug-in

Place the plug-in's login folder in the same folder as your landing page.

There are two recipes for responding to whether a user is logged in, one for pages that are viewable only by logged-in users, and one for pages that differ for logged in users. On each page that is to be accessible only to logged in users, place the following at the beginning of the file, where ../index.php is a URL for the landing page:

   if (empty($_SESSION['userId'])) {
      header('Location: ../index.php');

On pages that are to differ for logged in users, bracket portions that are only for logged in users as follows:

   session_start(); // Only say this once
   if (isset($_SESSION['userId']))
      echo <<<EOT
         // material for the logged in user

In this design, user roles are numbered from 0 to 15, with 15 being the admin role, and 0 being the disabled role for users that are no longer allowed to log in. The use of roles 1 - 14 is optional and is independent of the login mechanism. The actual mechanism for distinguishing among user roles is similar to that for distinguishing among users:

   session_start(); // Only say this once
   if (isset($_SESSION['role'] &&
      $_SESSION['role'] >= n))
      echo <<<EOT
         // material for logged in users in roles  >= n

Implementation Points of Interest

This plug-in cannot constructed atop a MySQL database, as MySQL requires separate site-dependent, manual installation steps. Two kinds of databases that could be used for this application are SQLite and the NoSQL database, SDB. Both of these include functions for creating the initial database. This implementation uses an ad hoc database that provided the inspiration for SDB. If having a well-accepted underlying database is important, I suggest Chad Smith's mechanism based on SQLite3 with PDO.

A useful feature of MySQL is that the database is in a place that is hard to get to. At first thought this feature seems to be absent in a drop-in plug-in with an automatically constructed database. However, we have borrowed a technique from Brian R. McBride: We include an .htaccess file that prevents viewers from browsing sensitive files, even if they are in the same directory as other files intended for viewing.

Most of the forms used rely on AJAX rather than the HTML form element, as the former allows a more straightforward implementation. For more on this point, see "Formless" HTML Forms.