Apache HTTP Authentication with PHP

Share this article

At one time or another, we’ve all had to log into a password-protected Web site. When building a site, you may decide to require this of your visitors for several reasons. The first, and most obvious, is to protect secure information so that it can only be viewed by a select few. But you may also choose to assign usernames and passwords to casual visitors. This may be done in order to keep track of who is viewing your site, or to provide personalized options and services to your visitors.

The easiest way to password-protect a site is to use HTTP Authentication, where if a browser’s request for a protected page is not accompanied by the correct username and password, the Web server replies with an HTTP 401 error – which means “Unauthorized Access” – and an invitation for the browser to re-submit the request with a proper username and password. From the user’s point of view, most of this dialogue is hidden. Following that first failed request, the browser prompts the user (in a dialog box) for a username and password, and then re-submits the request, this time with the authentication information attached. Assuming the username/password combo is on the list of allowed users, the Web server then sends the page requested. The Web browser will likewise continue to send that username/password with all subsequent requests.

The most common way to set up an HTTP Authentication scheme is using an Apache “htaccess” file (see http://hoohoo.ncsa.uiuc.edu/docs/tutorials/user.html), but this method has disadvantages. Making the list of authorized users dynamic (so that users could register themselves and gain immediate access to your site, for example) can involve some pretty twisty server-side scripts that would have to manipulate the htaccess file(s) to add and remove users as appropriate. And keeping any kind of record as to who is accessing what using which username/password combinations is next to impossible using the basic support for HTTP Authentication in most Web servers.

Enter PHP, a free, open-source, cross-platform, server-side scripting language. When installed as an Apache module (this will not work with the CGI and ISAPI versions), PHP lets you handle HTTP Authentication by yourself, using any means you like to determine whether to accept or deny access to a Web site.
From here on I’ll assume that you are familiar with the basics of PHP. If this language is new to you, or if you need a refresher, Part 3 of my Building a Database-Driven Web Site series should bring you up to speed.

When installed as an Apache module, PHP provides two special global variables: $PHP_AUTH_USER and $PHP_AUTH_PW. These contain the username and password that accompanied the current HTTP request, respectively. Using PHP’s header() function, you can then respond with an HTTP 401 error when the username, password, or both are incorrect.

Let’s look at some sample code for a page that may only be viewed if the user enters username "myuser" and password "mypass":

<?php  
if ($PHP_AUTH_USER != "mysuser"  
   or $PHP_AUTH_PW != "mypass"):  
 // Bad or no username/password.  
 // Send HTTP 401 error to make the  
 // browser prompt the user.  
 header("WWW-Authenticate: " .  
        "Basic realm="Protected Page: " .  
        "Enter your username and password " .  
        "for access."");  
 header("HTTP/1.0 401 Unauthorized");  
 // Display message if user cancels dialog  
 ?>  
 <HTML>  
 <HEAD><TITLE>Authorization Failed</TITLE></HEAD>  
 <BODY>  
 <H1>Authorization Failed</H1>  
 <P>Without a valid username and password,  
    access to this page cannot be granted.  
    Please click 'reload' and enter a  
    username and password when prompted.  
 </P>  
 </BODY>  
 </HTML>  
<?php else: ?>  
 ...page contents here...  
<?php endif; ?>

As you can see, checking the username and password entered is as simple as checking the variables $PHP_AUTH_USER and $PHP_AUTH_PW. When an incorrect user/pass combination is detected, you respond with two HTTP headers (using the PHP header function):

WWW-Authenticate: Basic realm="Prompt the user here."  
HTTP/1.0 401 Unauthorized

The first line informs the Web browser that Basic authentication is to be used. This just means that authentication is to be done with a username and password. The realm option lets the browser know when a particular username/password should be used when navigating throughout a group of Web pages. All pages that should use the same username/password (thus saving the user from having to re-enter them for every page) should have the same realm specified. Since this string is displayed in the dialog prompting the user, it’s an ideal place to put a message (for example: “If you’re a new user, enter ‘guest’ for your username and leave the password blank.”). Note that the double quotes in this line must be escaped with backslashes to prevent them from interfering with the double quotes surrounding the string in your PHP code.

The second line is a standard HTTP response code that lets the browser know that the username/password entered (if any) was incorrect, and that the user should be prompted to (re)enter them.

To protect an entire site, you would typically use PHP’s include function to use the code that performs the username/password check in every file on your site that you want protected without having to retype said code on every page.

I recently used this technique on a site that I set up for a small group of people working on a project together. I issued a single username/password combination that gave them access to the registration page, where each of them would create a personal username/password combination. The registration page would store those combinations in a MySQL database (for more information on this, see my Building a Database-Driven Web Site article series). All the other pages on the site would then access that database to determine if a given username/password combination was allowed to access the site or not.

This and other creative possibilities for making your password protection system more flexible make HTTP Authentication using PHP an extremely handy tool to have in your arsenal.

Frequently Asked Questions (FAQs) about HTTP Authentication in PHP

What is HTTP Authentication in PHP?

HTTP Authentication in PHP is a method used to restrict access to certain parts of your website by requiring visitors to provide a username and password. This is achieved by sending a ‘WWW-Authenticate’ header, to which the client responds with an ‘Authorization’ header containing the encoded credentials. PHP provides built-in functions to handle this process, making it a straightforward way to add an extra layer of security to your website.

How do I implement HTTP Authentication in PHP?

Implementing HTTP Authentication in PHP involves using the ‘header’ function to send a ‘WWW-Authenticate’ header, then checking the ‘$_SERVER[‘PHP_AUTH_USER’]’ and ‘$_SERVER[‘PHP_AUTH_PW’]’ variables for the provided credentials. If these variables are not set or the credentials are incorrect, you can send the ‘WWW-Authenticate’ header again to prompt the user to enter their credentials.

Why isn’t my HTTP Authentication working?

There could be several reasons why your HTTP Authentication isn’t working. One common issue is that the ‘$_SERVER[‘PHP_AUTH_USER’]’ and ‘$_SERVER[‘PHP_AUTH_PW’]’ variables are not being set. This could be due to your server configuration or because you’re not checking these variables after sending the ‘WWW-Authenticate’ header. Another possible issue is that the credentials provided by the user are not being checked correctly.

Can I use HTTP Authentication with other types of authentication?

Yes, HTTP Authentication can be used in conjunction with other types of authentication. For example, you could use HTTP Authentication to restrict access to certain parts of your website, while using a different method, such as cookies or sessions, to manage user logins.

How secure is HTTP Authentication?

While HTTP Authentication provides an extra layer of security, it should not be relied upon as the sole method of protecting sensitive data. The credentials are sent as plain text with each request, meaning they could be intercepted if the connection is not secure. Therefore, it’s recommended to use HTTP Authentication in conjunction with other security measures, such as SSL encryption.

How can I customize the authentication prompt?

The authentication prompt displayed to the user is controlled by the browser, not PHP. However, you can customize the message that appears in the prompt by changing the ‘realm’ parameter in the ‘WWW-Authenticate’ header.

Can I log out a user with HTTP Authentication?

HTTP Authentication does not provide a built-in way to log out a user. Once the user has entered their credentials, they will remain authenticated until they close their browser. However, you can effectively log out a user by changing the ‘realm’ parameter in the ‘WWW-Authenticate’ header, which will prompt the user to enter their credentials again.

Can I use HTTP Authentication with AJAX?

Yes, HTTP Authentication can be used with AJAX. However, because AJAX requests are made in the background, the user will not see an authentication prompt. Instead, you will need to include the credentials in the AJAX request itself.

Why am I seeing a “401 Unauthorized” error?

A “401 Unauthorized” error is returned when the user fails to provide valid credentials after receiving a ‘WWW-Authenticate’ header. This could be because the user entered their credentials incorrectly, or because the credentials were not checked correctly on the server.

Can I use HTTP Authentication with a database?

Yes, HTTP Authentication can be used with a database. Instead of hardcoding the valid credentials in your script, you can check the ‘$_SERVER[‘PHP_AUTH_USER’]’ and ‘$_SERVER[‘PHP_AUTH_PW’]’ variables against the credentials stored in your database.

Kevin YankKevin Yank
View Author

Kevin Yank is an accomplished web developer, speaker, trainer and author of Build Your Own Database Driven Website Using PHP & MySQL and Co-Author of Simply JavaScript and Everything You Know About CSS is Wrong! Kevin loves to share his wealth of knowledge and it didn't stop at books, he's also the course instructor to 3 online courses in web development. Currently Kevin is the Director of Front End Engineering at Culture Amp.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week