<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/features.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'en',
  ),
  'this' => 
  array (
    0 => 'features.http-auth.php',
    1 => 'HTTP authentication with PHP',
    2 => 'HTTP authentication with PHP',
  ),
  'up' => 
  array (
    0 => 'features.php',
    1 => 'Features',
  ),
  'prev' => 
  array (
    0 => 'features.php',
    1 => 'Features',
  ),
  'next' => 
  array (
    0 => 'features.cookies.php',
    1 => 'Cookies',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'en',
    'path' => 'features/http-auth.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="features.http-auth" class="chapter">
  <h1 class="title">HTTP authentication with PHP</h1>


  <p class="simpara">
   It is possible to use the 
   <span class="function"><a href="function.header.php" class="function">header()</a></span> function to send an <code class="literal">&quot;Authentication Required&quot;</code> 
   message to the client browser causing it to pop up a Username/Password 
   input window.  Once the user has filled in a username and a password, 
   the URL containing the PHP script will be called again with the 
   <a href="reserved.variables.php" class="link">predefined variables</a> 
   <var class="varname">PHP_AUTH_USER</var>, <var class="varname">PHP_AUTH_PW</var>, 
   and <var class="varname">AUTH_TYPE</var> set to the user name, password and 
   authentication type respectively.  These predefined variables are found 
   in the <var class="varname"><a href="reserved.variables.server.php" class="classname">$_SERVER</a></var> array. <em>Only</em>
   the &quot;Basic&quot; authentication method is supported. See the
   <span class="function"><a href="function.header.php" class="function">header()</a></span> function for more information.
  </p>

  <p class="para">
   An example script fragment which would force client authentication
   on a page is as follows:
  </p>
  <p class="para">
   <div class="example" id="example-1">
    <p><strong>Example #1 Basic HTTP Authentication example</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">if (!isset(</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_USER'</span><span style="color: #007700">])) {<br />    </span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'HTTP/1.1 401 Unauthorized'</span><span style="color: #007700">);<br />    </span><span style="color: #0000BB">header</span><span style="color: #007700">(</span><span style="color: #DD0000">'WWW-Authenticate: Basic realm="My Realm"'</span><span style="color: #007700">);<br />    echo </span><span style="color: #DD0000">'Text to send if user hits Cancel button'</span><span style="color: #007700">;<br />    exit;<br />} else {<br />    echo </span><span style="color: #DD0000">"&lt;p&gt;Hello </span><span style="color: #007700">{</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_USER'</span><span style="color: #007700">]}</span><span style="color: #DD0000">.&lt;/p&gt;"</span><span style="color: #007700">;<br />    echo </span><span style="color: #DD0000">"&lt;p&gt;You entered </span><span style="color: #007700">{</span><span style="color: #0000BB">$_SERVER</span><span style="color: #007700">[</span><span style="color: #DD0000">'PHP_AUTH_PW'</span><span style="color: #007700">]}</span><span style="color: #DD0000"> as your password.&lt;/p&gt;"</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </p>

  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <strong>Compatibility</strong><br />
   <p class="para">
    Please be careful when coding the HTTP header lines. In order to guarantee maximum
    compatibility with all clients, the keyword &quot;Basic&quot; should be written with an
    uppercase &quot;B&quot;, the realm string must be enclosed in double (not single) quotes,
    and exactly one space should precede the <em>401</em> code in the 
    <em>HTTP/1.1 401</em> header line. Authentication parameters have
    to be comma-separated.
   </p>
  </p></blockquote>

  <p class="para">
   Instead of simply printing out <var class="varname">PHP_AUTH_USER</var> 
   and <var class="varname">PHP_AUTH_PW</var>, as done in the above example, 
   you may want to check the username and password for validity.  
   Perhaps by sending a query to a database, or by looking up the 
   user in a dbm file.
  </p>

  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <strong>Apache Configuration</strong><br />
   <p class="para">
    PHP uses the presence of an <code class="literal">AuthType</code> directive
    to determine whether external authentication is in effect.
   </p>
  </p></blockquote>

  <p class="simpara">
   Note, however, that the above does not prevent someone who
   controls a non-authenticated URL from stealing passwords from
   authenticated URLs on the same server.
  </p>

  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <strong>Browser behavior</strong><br />
   <span class="simpara">
    HTTP Basic authentication really is basic, and it wasn&#039;t designed to support
    logouts. Because HTTP is a stateless protocol, most browsers will cache the
    provided credentials as soon as a <code class="literal">2xx</code> status code is seen,
    and will send them in every request, until the browser is closed. There is no
    defined way for a server to request a new prompt for credentials.

    Over the years, various workarounds for this have spread as advice on the internet,
    but they all depend on how different browsers have chosen to handle undefined edge
    cases (or even violations of the HTTP standard). It is best to avoid such
    workarounds and not use Basic authentication for anything serious.
   </span>
  </p></blockquote>

  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <strong>IIS Configuration</strong><br />
   <span class="simpara">
    In order to get HTTP Authentication to work on IIS server with the CGI version of
    PHP, the php.ini directive <a href="ini.core.php#ini.cgi.rfc2616-headers" class="link">cgi.rfc2616_headers</a>
    must be set to <code class="literal">0</code> (the default value), and you must edit your IIS
    configuration &quot;<code class="literal">Directory Security</code>&quot;.
    Click on &quot;<code class="literal">Edit</code>&quot; and only check &quot;<code class="literal">Anonymous Access</code>&quot;,
    all other fields should be left unchecked.
   </span>
  </p></blockquote>

 </div>
<?php manual_footer($setup); ?>