HTTP authentication with PHP-CGI

HTTP authentication is ugly, but it can be useful if you need to enforce a login but you can’t expect a user to be able to log in interactively. For example, if you want to provide a restricted Atom feed, you can’t expect your users’ feed reader software to set your site’s login cookie by running through your HTML-based login process, but you can reasonably expect the software to understand HTTP basic authentication.

Unfortunately, if PHP is running under CGI — as is the default with PHP 5 on Dreamhost — then your PHP scripts typically cannot use HTTP authentication. Happily, there is a workaround; you can use mod_rewrite to pass HTTP authentication info to your scripts as a GET parameter.

This is adapted from these instructions by janhsh.

First, you need to set up an .htaccess file.

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /basedir/
    RewriteCond %{HTTP:Authorization} ^Basic.*
    RewriteRule (.*) index.php?Authorization=%{HTTP:Authorization} [QSA,L]
</IfModule>

In this example, HTTP auth info will be passed to the script index.php through a GET parameter called Authorization. The QSA bit means that any additional GET parameters will also be passed to your script.

Your PHP script could look something like this:

<?php
$authorized = false;

if (isset($_GET['Authorization'])) {
    // Check for the HTTP authentication string in $_GET['Authorization'], 
    // and put it in the $auth variable
    if (preg_match('/Basic\s+(.*)$/i', $_GET['Authorization'], $auth)) {
        // Split the string, base64 decode it, and place the values into 
        // the $authName and $authPassword variables
        list($authName, $authPassword) = explode(':', base64_decode($auth[1]));
        // Check the values of $authName and $authPass using your login routine
        if (do_some_sort_of_login_check($authName, $authPassword)) {
            $authorized = true;
        }
    }
}

if ($authorized) {
    // Success!  Display your content
    display_your_restricted_content();
} else {
    // Force the browser to prompt for a username and password
    header('WWW-Authenticate: Basic realm="name of your realm"');
    header('HTTP/1.0 401 Unauthorized');
    display_http_401_page();
}

[ article last updated 2007-02-27 22:04:09 by cobra libre ]