Using HTTP authentication with PHP

This topic is intended for advanced users who are familiar with PHP's HTTP authentication functions, and who want to password protect a PHP file, then find out the username and password that the visitor provided so they can be used in the PHP script.

As mentioned on PHP's "HTTP authentication with PHP" page, "the HTTP authentication hooks in PHP are only available when it is running as an Apache module and is hence not available in the CGI version". (Update: that text appears to have been removed from the PHP page for some reason, but it's still true, as the page comments attest.)

We use the CGI version of PHP for added security, so you can't normally use the "PHP_AUTH_USER" and "PHP_AUTH_PW" variables. However, there is a way to "trick" Apache and PHP into doing this. Just follow the instructions below.

Step 1: Create a .htaccess file

First of all, create a .htaccess file in the same directory as your PHP script. The file should contain these two lines:

RewriteEngine on
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]

That tells the Apache Web server to pass the encrypted username and password to PHP in a variable named HTTP_AUTHORIZATION.

Step 2: Add extra PHP code before using PHP_AUTH_USER or PHP_AUTH_PW

In the PHP script, include this code before using the PHP_AUTH_USER or PHP_AUTH_PW variables:

if (preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches))
{
    list($name, $password) = explode(':', base64_decode($matches[1]));
    $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
    $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
}

That allows PHP to use the HTTP_AUTHORIZATION variable to extract the PHP_AUTH_USER and PHP_AUTH_PW variables.

A complete example of a simple PHP script that uses this technique might look like this:

<?php
    if (preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches))
    {
        list($name, $password) = explode(':', base64_decode($matches[1]));
        $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
        $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
    }
    echo "<p>Username is ", $_SERVER['PHP_AUTH_USER'], "</p>";
    echo "<p>Password is ", $_SERVER['PHP_AUTH_PW'], "</p>";
?>