9

我試圖使用Basic HTTP Authentication並遵循PHP手冊頁上的示例。但它不適合我。變量$_SERVER['PHP_AUTH_USER']似乎沒有設置。當用戶嘗試登錄時,會提示用戶有新的登錄對話框。服務器正在運行PHP 5.3.3,我已經嘗試使用Google Chrome和Internet Explorer。如何在PHP中使用基本HTTP身份驗證?

下面是簡單的例子,我用:

<?php 
if (!isset($_SERVER['PHP_AUTH_USER'])) { 
    header('WWW-Authenticate: Basic realm="Jonas Realm"'); 
    header('HTTP/1.0 401 Unauthorized'); 
    echo 'User pressed Cancel'; 
    exit; 
} else { 
    echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>"; 
    echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as you password.</p>"; 
} 
?> 

有什麼不對?我如何在PHP中使用基本HTTP身份驗證?

+0

而不是試圖用PHP來做到這一點,爲什麼你不使用Web服務器,例如http://httpd.apache.org/docs/2.2/howto/auth.html – Phil 2010-11-11 00:52:55

+1

@James:我想我的網站主機使用Apache。 – Jonas 2010-11-11 00:53:28

+1

@Phil:那麼我的PHP代碼將與我的Web服務器無關,並且我不能更改爲另一個Web服務器。我想遵循HTTP標準。 – Jonas 2010-11-11 00:54:39

回答

8

PHP如何運行?如果它通過Apache mod_cgi,恐怕你根本無法獲得認證信息。除非用SECURITY_HOLE_PASS_AUTHORIZATION標誌編譯它,否則Apache不會將它傳遞給CGI應用程序。 (無論是否存在安全漏洞,取決於服務器上的其他用戶是否具有比您的網站用戶更低或更高的權限。)

如果是IIS CGI,則必須確保只有「匿名」目錄訪問權限配置,或IIS將嘗試介入並驗證憑據本身。

echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>"; 

HTML注入安全漏洞(以及它的工作原理)。使用htmlspecialchars()。男人,是PHP文檔頁面充滿了高度可疑的建議和代碼。

您也可以嘗試查看$_SERVER['HTTP_AUTHORIZATION'],但我懷疑這是mod_cgi問題,在這種情況下,兩個變量都不會出現,您將不得不求助於基於cookie的登錄。或者使用更現代的PHP託管方法(如FastCGI或mod_php)更改爲主機。

0

我認爲PHP方法依賴於Web服務器上配置的基本身份驗證。執行此操作的簡單方法是在要啓用基本身份驗證的目錄中包含.htaccess文件。

大多數基於Unix的網絡主機允許你通過上傳這個文件來做到這一點。一個單獨的文件(稱爲.htauth)將保存允許訪問站點或目錄的用戶登錄名。

+1

這是不正確的。 PHP可以完全控制發送給客戶端(瀏覽器)的頭文件。 – Phil 2010-11-11 01:00:30

+0

@phil不正確。 Apache總是發送一個「Server:」標題,而PHP不能阻止這種情況。 – 2013-05-24 10:47:16

4

試試這個::

<?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((isset($_SERVER['PHP_AUTH_USER']) && ($_SERVER['PHP_AUTH_USER'] == "leon")) AND 
     (isset($_SERVER['PHP_AUTH_PW']) && ($_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"); 
    } 
?> 
7

對於PHP,CGI:

在.htaccess補充一點:

<IfModule mod_rewrite.c> 
RewriteEngine on 
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] 
</IfModule> 

,並在你的腳本的開頭補充一點:

list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); 
+0

'substr()'是可疑的。我首先會在第一個空格處打斷字符串,並確保認證類型確實設置爲「Basic」(忽略大小寫)。然後獲取第二部分並對其進行解碼。 – 2017-08-21 21:02:45

0

檢查您是否侵犯了您r變量$_SERVER[‘PHP_AUTH_USER’]$_SERVER[‘PHP_AUTH_PW’]之前您嘗試訪問這兩個變量的地方。

如果上面不是這種情況,那麼chek,如果你使用PHP作爲CGI MOD或不。如果你使用php作爲cgi mod,那麼在大多數情況下,你不會得到$_SERVER[‘PHP_AUTH_USER’]$_SERVER[‘PHP_AUTH_PW’],因爲通常我們不用編譯Apache的選項SECURITY_HOLE_PASS_AUTHORIZATION 因此,如果你想獲得兩個變量,然後用選項SECURITY_HOLE_PASS_AUTHORIZATION重新編譯apache或您可以使用在PHP basic auth後解釋的.htaccess方法。