28

Tôi có một máy chủ dựa trên REST mà tôi đang cố gắng giao tiếp với việc sử dụng JQuery. Cả XML và JSON đều có sẵn dưới dạng các định dạng phản hồi, vì vậy tôi đang sử dụng JSON.Cuộc gọi JQuery Ajax với Xác thực cơ bản HTTP

Các kết nối được tất cả SSL để HTTP Basic Authentication đã được phương pháp uỷ quyền của chúng ta về sự lựa chọn, và chúng tôi đã không có vấn đề với đầu phía trước khác (nguyên Javascript, Silverlight, vv ...)

Bây giờ tôi đang cố gắng để đặt một cái gì đó cùng với JQuery và có vấn đề vô tận bằng cách sử dụng xác thực cơ bản HTTP.

Tôi đã lùng sục qua nhiều câu hỏi trước, hầu hết trong số đó có giải pháp dường như không thực sự hoạt động hoặc đổ lỗi cho toàn bộ vấn đề truy cập nguồn gốc chéo mà tôi đã vượt qua trong thử nghiệm Javascript cơ bản. Câu trả lời luôn cung cấp Access-Control-Allow-Origin được đặt thành tiêu đề Gốc được cung cấp trong yêu cầu và điều này có thể được nhìn thấy trong phản hồi của các bài kiểm tra của tôi.

Trong javascript cơ bản, toàn bộ cuộc gọi này là rất đơn giản thực hiện với:

req.open('GET', 'https://researchdev-vm:8111/card', true, 'test', 'testpassword'); 

Nỗ lực JQuery ở đây là khá chuẩn:

 $.ajax({ 
     username: 'test', 
     password: 'testpassword', 
     url: 'https://researchdev-vm:8111/card', 
     type: 'GET', 
     dataType: 'json', 
     crossDomain: true, 
     /*data: { username: 'test', password: 'testpassword' },*/ 
     beforeSend: function(xhr){ 
      xhr.setRequestHeader("Authorization", 
       //"Basic " + encodeBase64(username + ":" + password)); 
       "Basic AAAAAAAAAAAAAAAAAAA="); 
     }, 
     sucess: function(result) { 
      out('done'); 
     } 
    }); 

Phương pháp duy nhất mà thực sự dường như làm việc để cung cấp xác thực là chèn trực tiếp dữ liệu được mã hóa Base64 vào hàm beforeSend(). Nếu điều này không được bao gồm, không có tiến bộ nào được thực hiện. Các thuộc tính tên người dùng và mật khẩu dường như bị bỏ qua hoàn toàn.

Với hành vi beforeSend() được cung cấp, cuộc gọi GET nhận được phản hồi tích cực với dữ liệu được bao gồm. Tuy nhiên, vì đây là cuộc gọi chéo, cuộc gọi OPTIONS được thực hiện trước cuộc gọi GET và luôn thất bại, vì nó không sử dụng beforeSend() và do đó nhận được phản hồi 401 do xác thực không thành công.

Có cách nào tốt hơn để thực hiện những gì nên là một cuộc gọi rất tầm thường? Nếu thực tế là yêu cầu OPTIONS không sử dụng chế biến chức năng beforeSend() thì có thể coi là lỗi không? Có lẽ một cách để vô hiệu hóa kiểm tra OPTIONS hoàn toàn? Không thể thực hiện cuộc gọi này không phải là cross-site, vì Javascript dường như xem xét ngay cả một số cổng khác trên cùng một máy như "cross-site".

+0

Bạn không cần phải có trước khi gửi VÀ/lĩnh vực mật khẩu Tên truy nhập . Tôi sẽ loại bỏ các trường tên người dùng/mật khẩu từ hàm $ .ajax của bạn. –

Trả lời

1

Đây là điều hoạt động như xác thực chuyển tiếp cho cuộc gọi AJAX. Điều này dựa trên NTLM để xác thực trên trang mà javascript sẽ thực thi. Có lẽ đây sẽ giúp bạn:

PHP Code:

<?php 
$headers = apache_request_headers(); 
if (isset($headers['Authorization'])) 
    echo "<script>var auth = " . $headers['Authorization'] . "</script>"; 
unset($headers); 
?> 

Sử dụng jQuery bạn sẽ sử dụng nó theo cách này:

$.ajax({ 
     type: 'POST', 
     url: './somePage.php', 
     data: {"test":true}, 
     dataType: 'json', 
     success: function(data) { 
      console.log(data.username); 
     }, 
     beforeSend : function(req) { 
      req.setRequestHeader('Authorization', auth); // <<<<----- USED HERE 
     }, 
}); 

Đối với XMLHttpRequest tiêu chuẩn:

var xml = new XMLHttpRequest(); 
xml.open('GET', './somePage.php', true); 
xml.setRequestHeader('Authorization', auth); // <<<<----- USED HERE 
xml.send(); 
+0

Sẽ hữu ích nếu bạn cung cấp ví dụ về biến 'auth' trông như thế nào. Tôi tưởng tượng nó là một đối tượng với các thuộc tính người dùng và mật khẩu, nhưng tốt nhất là phải rõ ràng về điều đó – TKoL

+0

@TKoL OP cung cấp một ví dụ về giá trị 'auth'. Về cơ bản, đó là: '" Basic "+ encodeBase64 (tên người dùng +": "+ mật khẩu));' –

+0

nhờ @ wes.hysell. Đối với tôi điều đó không rõ ràng. – TKoL

3

Câu hỏi này có lẽ cũng đã qua ngày hết hạn của nó, nhưng tôi đã làm việc với điều tương tự với Jquery và đã đi qua Ame vấn đề.

Thuộc tính tên người dùng và mật khẩu dường như không thực hiện mã hóa base64 của tên người dùng/mật khẩu như bạn thường làm để thực hiện xác thực cơ sở HTTP.

Nhìn vào các yêu cầu sau (rút ngắn cho ngắn gọn), trước hết bằng cách sử dụng "username" và "password" tham số trong phương pháp JQuery AJAX:

Request URL:http://testuser%40omnisoft.com:[email protected]:60023/Account 
Request Method:GET 
Accept:application/json, text/javascript, */*; q=0.01 
Host:localhost:60023 

Và bây giờ với phương pháp beforeSend:

Request URL:http://localhost:60023/Account 
Request Method:GET 
Accept:application/json, text/javascript, */*; q=0.01 
Authorization:Basic dXNlcm5hbWU6cGFzc3dvcmQ= 
Host:localhost:60023 

Lưu ý rằng phương thức đầu tiên không bao gồm tiêu đề 'Ủy quyền' trong yêu cầu, nhưng thay vào đó hãy thêm tiền tố vào URL mục tiêu. Tôi không có chuyên gia về auth cơ bản HTTP, nhưng nó sẽ chỉ ra rằng trước đây không phải là một thực hiện đúng và do đó không thành công (hoặc ít nhất là nó với việc thực hiện máy chủ của riêng tôi).

Theo yêu cầu OPTIONS của bạn bằng cách sử dụng JSONP - bạn có thể thử sử dụng ?callback=? trong URL của mình thay vì sử dụng tùy chọn crossdomain, chỉ để rõ ràng.

1

Đối với bất kỳ ai đến qua vấn đề này, tôi đã giải quyết vấn đề chặn các yêu cầu OPTIONS với Apache và chỉ chuyển tiếp các GET và POST tới chương trình phụ trợ.

Giải pháp này là appserver độc lập và do đó làm việc cho PHP và Java cũng như:

<VirtualHost *:80> 

    # ServerName and other configuration... 


    # CORS 
    Header set Access-Control-Allow-Origin "*" 
    Header set Access-Control-Allow-Methods "OPTIONS, GET, PUT, POST" 
    Header set Access-Control-Allow-Headers "Authorization" 

    # Intercept OPTIONS calls 
    RewriteEngine On 
    RewriteCond %{REQUEST_METHOD} ^(OPTIONS)$ 
    RewriteRule .* - [L] 

    # Backend, adapt this line to fit your needs 
    RewriteRule /(.*) ajp://localhost:8010/$1 [L,P] 

</VirtualHost> 

Kính trọng, Maurizio

+0

Để triển khai REST phù hợp, có thể bạn sẽ muốn bao gồm phương thức 'PUT'. –

+0

dứt khoát, cảm ơn Jezen! – Maurix

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