header() işlevi kullanılarak istemci tarayıcısına "Kimlik Doğrulaması Gerekli" ("Authentication Required") iletisini göndererilir ve bunun sonucunda Kullanıcı Adı/Parola giriş penceresi açılır. Kullanıcı kullanıcı adı ve parolasını girdiğinde, PHP betiğini içeren URL, kullanıcı adı, parola ve kimlik doğrulama türünü atayan PHP_AUTH_USER, PHP_AUTH_PW ve AUTH_TYPE öntanımlı değişkenleri ile tekrar çağrılır. Bu öntanımlı değişkenler $_SERVER ve $HTTP_SERVER_VARS dizileri içinde bulunur. "Temel" ve "Özet" (PHP 5.1.0'dan itibaren) kimlik doğrulama yöntemlerinin ikisi de desteklenir. Daha fazla bilgi için header() işlevine bakınız.
Bilginize: PHP Sürüm Bilgisi
$_SERVER gibi süper küreseller, PHP » 4.1.0'dan itibaren kullanılabilmektedir.
İstemci sayfasını kimlik doğrulamaya zorlayacak örnek betik aşağıdaki gibidir:
Örnek 1 - Temel HTTP Kimlik Doğrulaması örneği
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Benim bölgem"');
header('HTTP/1.0 401 Unauthorized');
echo 'Kullanıcı İptal düğmesine basınca çıkacak metin';
exit;
} else {
echo "<p>Merhaba {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>Parola olarak {$_SERVER['PHP_AUTH_PW']} verdiniz.</p>";
}
?>
Örnek 2 - Özet HTTP Kimlik Doğrulaması örneği
Bu örnek basit bir Özet HTTP kimlik doğrulama betiğinin nasıl uygulanacağını gösterir. Daha fazla bilgi için » RFC 2617 belgesini okuyunuz.
<?php
$saha = 'Kısıtlanmış alan';
// kullanici => parola
$kullanicilar = array('yonetici' => 'gizlisifre', 'misafir' => 'misafir');
if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$saha.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($saha).'"');
die('Kullanıcı İptal düğmesine basınca çıkacak metin');
}
// PHP_AUTH_DIGEST değişkenini inceleyelim
if (!($veri = http_ozet_cozumle($_SERVER['PHP_AUTH_DIGEST'])) ||
!isset($kullanicilar[$veri['username']]))
die('Kimlik Doğrulama Hatası!');
// geçerli yanıt üretimi
$A1 = md5($veri['username'] . ':' . $saha . ':' .
$kullanicilar[$veri['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$veri['uri']);
$gecerli_yanit = md5($A1.':'.$veri['nonce'].':'.$veri['nc'].':'.
$veri['cnonce'].':'.$veri['qop'].':'.$A2);
if ($veri['response'] != $gecerli_yanit)
die('Kimlik Doğrulama Hatası!');
// tamam, geçerli kullanıcı adı & parolası
echo 'Hoşgeldiniz : ' . $veri['username'];
// http kimlik doğrulama başlığını çözümleyecek işlev
function http_ozet_cozumle($metin)
{
// eksik veriye karşı koruma
$gerekli_kisimlar = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1,
'username'=>1, 'uri'=>1, 'response'=>1);
$veri = array();
$keys = implode('|', array_keys($gerekli_kisimlar));
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@',
$metin, $eslesen, PREG_SET_ORDER);
foreach ($eslesen as $m) {
$veri[$m[1]] = $m[3] ? $m[3] : $m[4];
unset($gerekli_kisimlar[$m[1]]);
}
return $gerekli_kisimlar ? false : $veri;
}
?>
Bilginize: Uyumluluk Bilgisi
Lütfen HTTP başlık satırlarını kodlarken dikkatli olun. Bütün istemcilerle uyumluluğu garantilemek için, "Basic" anahtar sözcüğünün "B" harfi büyük yazılmalı, realm metni çift tırnak (tek tırnak değil) ile yazılmalı, ve HTTP/1.0 401 başlık satırındaki 401 kodundan önce tam olarak bir adet boşluk olmalıdır. Yukarıdaki özet örneğinde olduğu gibi kimlik doğrulama değiştirgeleri virgülle ayrılmış olmalıdır.
Yukarıdaki örnekte yapıldığı gibi sadece PHP_AUTH_USER ve PHP_AUTH_PW yazdırmak yerine, kullanıcı adı ve parolasının doğruluğunu denetlemek isteyebilirsiniz. Bunun için belki bir veritabanı sorgusu gönderebilir veya kullanıcıyı bir dbm dosyası içinde arayabilirsiniz.
Burada hatalı Internet Explorer tarayıcılarına dikkat ediniz. Başlıkların sırası konusunda çok seçici görünürler. WWW-Authenticate başlığını HTTP/1.0 401 başlığından önce göndermek hileye neden olabilir.
PHP 4.3.0'dan itibaren geleneksel harici kimlik doğrulama yönteminden geçmiş
bir sayfa için girilmiş parolayı gösteren bir betik yazılmasını engellemek
için, harici kimlik doğrulaması yapılan sayfa için güvenli kip (safe_mode
)
etkinleştirilir, böylece PHP_AUTH değişkenlerine değer atanmaz. Harici kimlik
doğrulaması yapılan kullanıcıyı kimliklendirmek için
REMOTE_USER değişkeni
$_SERVER['REMOTE_USER'] olarak kullanılabilir.
Bilginize: Yapılandırma Bilgisi
PHP harici kimlik doğrulamasının etkin olup olmadığnı tespit etmek için AuthType yönergesininin varlığını bakar.
Yukarıdaki örnek, aynı sunucudaki kimlik doğrulamalı URL'lerden girilen parolaları çalmak için kimlik doğrulamasız bir URL'yi kullanmak isteyenleri önlemez.
Hem Netscape Navigator hem de Internet Explorer, 401 sunucu yanıtını almak için yerel tarayıcı penceresinin kimlik doğrulama önbelleğini temizler. Bu işlem, kullanıcıları tekrar kullanıcı adı ve parolasını girmeye zorlayacak şekilde "oturumu kapatır". Bazıları bunu "zaman aşımlı" kullanıcı girişi için kullanırlar veya bir "Çıkış" düğmesi sunarlar.
Örnek 3 - Yeni kullanıcı adı va parolası girmeye zorlayan bir HTTP kimlik doğrulama örneği
<?php
function authenticate() {
header('WWW-Authenticate: Basic realm="Kimlik Doğrulaması Deneme Sistemi"');
header('HTTP/1.0 401 Unauthorized');
echo "Bu kaynağa erişmek için geçerli bir kullanıcı adı ve " .
"parolası girmelisiniz.\n";
exit;
}
if (!isset($_SERVER['PHP_AUTH_USER']) ||
($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
authenticate();
} else {
echo "<p>Merhaba: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />";
echo "Eski: " . htmlspecialchars($_REQUEST['OldAuth']);
echo "<form action='' method='post'>\n";
echo "<input type='hidden' name='SeenBefore' value='1' />\n";
echo "<input type='hidden' name='OldAuth' value='{$_SERVER['PHP_AUTH_USER']}' />\n";
echo "<input type='submit' value='Kimliği Yeniden Doğrula />\n";
echo "</form></p>\n";
}
?>
Bu davranış şekli HTTP Temel kimlik doğrulama standardı için gerekli değildir, bu nedenle buna güvenmemelisiniz. Lynx ile denendiğinde Lynx'in kimlik doğrulama kartlarını 401 sunucu yanıtı ile temizlemediğini göstermiştir, bu nedenle kimlik bilgisi değişmediği sürece geri ve ileri düğmesine basmak aynı kaynağı açacaktır. Kullanıcı '_' tuşu ile kimlik doğrulama bilgisini temizleyebilir.
Ayrıca PHP 4.3.3'e kadar, PHP'nin CGI sürümünü kullanan Microsoft'un IIS sunucularında IIS kısıtlaması nedeniyle HTTP kimlik doğrulaması çalışmaz. PHP 4.3.3 ve sonrasında bunun çalışması için IIS yapılandırmasındaki "Dizin Güvenliği"ni değiştirmelisiniz. "Düzenle"ye basınız ve sadece "Anonim Erişim"leri seçiniz, diğer bütün sahalar seçimsiz olmalıdır.
Diğer kısıtlama IIS modülü (ISAPI) ve PHP 4 kullanımında yaşanır. PHP_AUTH_* değişkenlerini kullanamazsınız, bunun yerine HTTP_AUTHORIZATION değişkeni kullanılabilir. Örnek: list($user, $pw) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
Bilginize: IIS Bilgisi:
HTTP kimlik doğrulamasının IIS ile çalışması için, PHP yönergesi cgi.rfc2616_headers değeri 0 olmaldır (öntanımlı değer).
Bilginize:
Eğer güvenli kip etkinse, betiğin kullanıcı kimliği değeri WWW-Authenticate başlığının realm kısmına eklenir.