9

Tôi đang cố gắng sử dụng Basic HTTP Authentication và làm theo ví dụ trên trang hướng dẫn sử dụng PHP. Nhưng nó không hiệu quả với tôi. Biến số $_SERVER['PHP_AUTH_USER'] dường như không được đặt. Khi người dùng cố gắng đăng nhập, người dùng sẽ được nhắc với hộp thoại đăng nhập mới. Máy chủ đang chạy PHP 5.3.3 và tôi đã thử với Google Chrome và Internet Explorer.Tôi làm cách nào để sử dụng Xác thực HTTP cơ bản trong PHP?

Dưới đây là ví dụ đơn giản mà tôi đã sử dụng:

<?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>"; 
} 
?> 

Điều gì là sai? Làm cách nào để sử dụng Xác thực HTTP cơ bản trong PHP?

+0

Thay vì cố gắng thực hiện điều này với PHP, tại sao bạn không sử dụng máy chủ web, ví dụ: http://httpd.apache.org/docs/2.2/howto/auth.html – Phil

+1

@James: Tôi nghĩ rằng trang web của mình máy chủ sử dụng Apache. – Jonas

+1

@Phil: Sau đó mã PHP của tôi sẽ bị từ chối của máy chủ web của tôi và tôi không thể thay đổi easyli sang một máy chủ web khác. Tôi muốn tuân theo tiêu chuẩn HTTP. – Jonas

Trả lời

8

PHP đang hoạt động như thế nào? Nếu thông qua Apache mod_cgi, tôi e rằng bạn không thể nắm giữ thông tin xác thực. Apache sẽ không chuyển nó cho các ứng dụng CGI trừ khi bạn biên dịch nó với cờ SECURITY_HOLE_PASS_AUTHORIZATION. (Cho dù đó thực sự là lỗ hổng bảo mật hay không phụ thuộc vào việc người dùng khác trên máy chủ của bạn có đặc quyền thấp hơn hoặc lớn hơn người dùng trang web của bạn hay không.)

Nếu IIS CGI, bạn phải đảm bảo rằng chỉ truy cập thư mục 'Chưa xác định' là cấu hình, hoặc IIS sẽ cố gắng bước vào và xác thực thông tin đăng nhập chính nó.

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

Lỗ bảo mật phun HTML (tốt, nếu nó hoạt động). Sử dụng htmlspecialchars(). Người đàn ông, là trang tài liệu PHP đầy đủ các lời khuyên và mã có vấn đề cao.

Bạn cũng có thể thử xem $_SERVER['HTTP_AUTHORIZATION'], mặc dù tôi nghi ngờ đó là vấn đề mod_cgi trong trường hợp không có biến nào sẽ hiện diện và bạn sẽ phải sử dụng đăng nhập dựa trên cookie. Hoặc thay đổi một máy chủ với cách tiếp cận hiện đại hơn đối với lưu trữ PHP, chẳng hạn như FastCGI hoặc mod_php.

0

Tôi nghĩ rằng các phương thức PHP dựa vào Xác thực cơ bản được định cấu hình trên Máy chủ web. Cách dễ dàng để thực hiện việc này là bao gồm tệp .htaccess trong thư mục bạn muốn bật xác thực cơ bản.

Hầu hết các máy chủ web dựa trên Unix đều cho phép bạn thực hiện việc này bằng cách chỉ tải lên tệp này. Một tệp riêng biệt (gọi đây là .htauth) sẽ giữ thông tin đăng nhập của người dùng được phép truy cập vào trang hoặc thư mục đó.

+1

Không chính xác. PHP hoàn toàn có thể kiểm soát các tiêu đề được gửi đến máy khách (trình duyệt). – Phil

+0

@phil không đúng sự thật. Apache luôn gửi một tiêu đề "Server:" và PHP không thể ngăn chặn điều đó. –

4

Hãy thử điều này ::

<?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

Đối với PHP-CGI:

trong .htaccess thêm này:

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

và vào lúc bắt đầu của kịch bản của bạn thêm này:

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

Đó là 'substr()' là đáng ngờ. Trước tiên, tôi sẽ phá vỡ chuỗi tại không gian đầu tiên và đảm bảo rằng loại xác thực thực sự được đặt thành 'Cơ bản' (bỏ qua trường hợp). Sau đó lấy phần thứ hai và giải mã nó. –

0

Kiểm tra xem bạn có ghi đè bạn không r biến $_SERVER[‘PHP_AUTH_USER’]$_SERVER[‘PHP_AUTH_PW’] trước vị trí bạn đang cố truy cập cả hai biến.

Nếu ở trên không phải là trường hợp thì hãy chek nếu bạn đang sử dụng php như cgi mod hay không. NẾU bạn đang sử dụng php như cgi mod thì trong hầu hết trường hợp bạn sẽ không nhận được $_SERVER[‘PHP_AUTH_USER’]$_SERVER[‘PHP_AUTH_PW’] bởi vì đại chúng ta không biên dịch apache với tùy chọn SECURITY_HOLE_PASS_AUTHORIZATION Vì vậy, nếu bạn muốn nhận cả hai biến sau đó biên dịch lại apache với tùy chọn SECURITY_HOLE_PASS_AUTHORIZATION hoặc bạn có thể sử dụng phương pháp tiếp cận .htaccess được giải thích trong bài đăng PHP basic auth.

Các vấn đề liên quan