| [ Team LiB ] |
|
24.1 HTTP AuthenticationIf you have any experience with the Web, you're familiar with basic HTTP authentication. You request a page, and a small dialog window appears asking for username and password. As described in Chapter 9, PHP allows you to open URLs with the fopen function. You can even specify a username and password in the URL in the same way you do in Navigator's location box. Authentication is implemented using HTTP headers, and you can protect your PHP pages using the header function. To protect a page with basic HTTP authentication, you must send two headers. The WWW-Authenticate header tells the browser that a username and password are required. It also specifies a realm that groups pages. A username and password are good for an entire realm, so users don't need to authenticate themselves with each page request. The other header is the status, which should be HTTP/1.0 401 Unauthorized. Compare this to the usual header, HTTP/1.0 200 OK. Listing 24.1 is an example of protecting a single page. The HTML to make a page is put into functions because it needs to be printed whether the authentication succeeds or fails. PHP creates the PHP_AUTH_USER and PHP_AUTH_PW elements of the _SERVER array automatically if the browser passes a username and password. The example requires leon for the username and secret for the password. A more complex scheme might match username and password against a list stored in a file or a database. Listing 24.1 Requiring authentication
<?php
/*
** Define a couple of functions for
** starting and ending an HTML document
*/
function startPage()
{
print("<html>\n");
print("<head>\n");
print("<title>Listing 24-1</title>\n");
print("</head>\n");
print("<body>\n");
}
function endPage()
{
print("</body>\n");
print("</html>\n");
}
/*
** test for username/password
*/
if(($_SERVER['PHP_AUTH_USER'] == "leon") AND
($_SERVER['PHP_AUTH_PW'] == "secret"))
{
startPage();
print("You have logged in successfully!<br>\n");
endPage();
}
else
{
//Send headers to cause a browser to request
//username and password from user
header("WWW-Authenticate: " .
"Basic realm=\"Leon's Protected Area\"");
header("HTTP/1.0 401 Unauthorized");
//Show failure text, which browsers usually
//show only after several failed attempts
print("This page is protected by HTTP " .
"Authentication.<br>\nUse <b>leon</b> " .
"for the username, and <b>secret</b> " .
"for the password.<br>\n");
}
?>
Now that you know how to protect a page, it may be instructive to work in the other direction, requesting a protected page. As I said earlier, the fopen function allows you to specify username and password as part of a URL, but you may have a more complicated situation in which you need to use fsockopen. An Authentication request header is necessary. The value of this header is a username and password separated by a colon. This string is base64 encoded in compliance with the HTTP specification. Listing 24.2 requests the script in Listing 24.1. You may need to modify the URI to make it work on your Web server. The script assumes you have installed all the examples on your Web server in /corephp/listings. If you are wondering about the \r\n at the end of each line, recall that all lines sent to HTTP servers must end in a carriage return and a linefeed. Listing 24.2 Requesting a protected document
<html>
<head>
<title>Listing 24-2</title>
</head>
<body>
<pre>
<?php
//open socket
if(!($fp = fsockopen("localhost", 80)))
{
print("Couldn't open socket!<br>\n");
exit;
}
//make request for document
fputs($fp, "HEAD /corephp/listings/24-1.php HTTP/1.0\r\n");
//send username and password
fputs($fp, "Authorization: Basic " .
base64_encode("leon:secret") .
"\r\n");
//end request
fputs($fp, "\r\n");
//dump response from server
fpassthru($fp);
?>
</pre>
</body>
</html>
|
| [ Team LiB ] |
|