JQuery ve Ajax ile temel kimlik doğrulamasını kullanma


419

Tarayıcı aracılığıyla temel bir kimlik doğrulaması oluşturmaya çalışıyorum, ancak oraya gerçekten ulaşamıyorum.

Bu komut dosyası burada olmazsa tarayıcı kimlik doğrulaması devralınır, ancak tarayıcıya kullanıcının kimlik doğrulaması yapmak üzere olduğunu söylemek istiyorum.

Adres şöyle olmalıdır:

http://username:password@server.in.local/

Bir form var:

<form name="cookieform" id="login" method="post">
      <input type="text" name="username" id="username" class="text"/>
      <input type="password" name="password" id="password" class="text"/>
      <input type="submit" name="sub" value="Submit" class="page"/>
</form>

Ve bir senaryo:

var username = $("input#username").val();
var password = $("input#password").val();

function make_base_auth(user, password) {
  var tok = user + ':' + password;
  var hash = Base64.encode(tok);
  return "Basic " + hash;
}
$.ajax
  ({
    type: "GET",
    url: "index1.php",
    dataType: 'json',
    async: false,
    data: '{"username": "' + username + '", "password" : "' + password + '"}',
    success: function (){
    alert('Thanks for your comment!');
    }
});

6
Yani tarayıcının BASIC kimlik doğrulamasını yapmasını istemiyor musunuz? Neden yalnızca form tabanlı kimlik doğrulaması kullanılmıyor?
no.good.at.coding

@ no.good.at.coding Kimlik doğrulamanın arkasında üçüncü taraf bir API ile entegre etmeniz gerekirse (yapmaya çalıştığım şey budur - developer.zendesk.com/rest_api/docs/core/… )
Brian Hannay

Yanıtlar:


467

beforeSendKimlik doğrulama bilgilerini içeren bir HTTP üstbilgisi eklemek için jQuery'nin geri aramasını kullanın :

beforeSend: function (xhr) {
    xhr.setRequestHeader ("Authorization", "Basic " + btoa(username + ":" + password));
},

6
u verdi örnek kullanıyorum ama çalışmıyor $ $ aax ({url: " server.in.local / index.php ", beforeSend: function (xhr) {xhr.setRequestHeader (“Yetkilendirme”, “Temel ”+ EncodeBase64 (“ kullanıcı adı: şifre ”));}, başarılı: function (val) {// alert (val); alert (" Yorumunuz için teşekkürler! ");}}); ``
Patrioticcow

69
beforeSend: function(xhr) { xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password)); };benim için çalışıyor
Rico Suter

12
Sorun ... Geçtiğim kimlik bilgileri başarısız olursa, Chrome'da kullanıcıya daha sonra kullanıcı adı / pwd'yi tekrar girmesi için bir iletişim kutusu sunulur. Kimlik bilgileri başarısız olursa bu 2. iletişim kutusunun görüntülenmesini nasıl önleyebilirim?
David

2
Bu, kimsenin görmesi için kullanıcı adını ve şifreyi açık bırakmayacak mı? Base64 olsa bile, sadece kodunu çözebilir. Aşağıdaki cevapla aynı.
cbron

6
@calebB Temel kimlik doğrulama genel olarak kullanıcı adını ve şifreyi herkesin görmesi için açık bırakır. Bu sadece burada açıklanan yöntemle ilgili bir sorun değildir. Temel kimlik doğrulaması veya gerçekten herhangi bir kimlik doğrulaması kullanılıyorsa, SSL de kullanılmalıdır.
Jason Jackson

354

Bir yılda işler nasıl değişir. Bunun yerine başlık özelliğine ek olarak xhr.setRequestHeader, mevcut jQuery (1.7.2+), $.ajaxçağrı ile birlikte bir kullanıcı adı ve şifre özelliği içerir .

$.ajax
({
  type: "GET",
  url: "index1.php",
  dataType: 'json',
  username: username,
  password: password,
  data: '{ "comment" }',
  success: function (){
    alert('Thanks for your comment!'); 
  }
});

Yorumlardan ve diğer yanıtlardan DÜZENLEME: Açık olmak gerekirse - kimlik denetimini (-1.7 öncesi) kullanmak 401 Unauthorizedyerine yanıt almadan önceden göndermek setRequestHeaderiçin 'headers':

$.ajax
({
  type: "GET",
  url: "index1.php",
  dataType: 'json',
  headers: {
    "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD)
  },
  data: '{ "comment" }',
  success: function (){
    alert('Thanks for your comment!'); 
  }
});

15
Olmamalı usernameve olmamalı usermı? Ayrıca tam olarak aynı değil: çevrimiçi docos ve deneyimim bazı API'ların gerektirdiği gibi önleyici değil gibi görünüyor. Başka bir deyişle, Authorizationbaşlığı yalnızca bir kod 401 döndürüldüğünde gönderir .
Stefano Fratini

3
@StefanoFratini - her iki konuda da haklısınız. Kullanıcı adı alanı düzeltildi ve önleyici kimlik doğrulaması ile yalnızca meydan okumaya yanıt verme hakkında bilgi sahibi olmak iyi. Başlığı diğer yanıtlarda olduğu gibi açık bir şekilde ayarlamak, bu 'pasif' temel yetkilendirme varyantının kullanılmasına izin verecektir.
jmanning2k

benim için yukarıdaki seçenek işe yaramadı, bu bir cazibe gibi çalıştı .. teşekkürler
Anoop Isaac

Yukarıdaki yoruma bakın, lütfen {"Yetkilendirme": "Temel" + btoa ("kullanıcı: geçiş")} 'i doğru başlık olarak belirtmek için bu yanıtı düzeltin
Jay

2
Aradığım cevap bu! Benim için bu cevabın en önemli yanı, 'başlık' ın kimlik denetimini önceden göndermek için nasıl kullanıldığıdır. Buradaki sorum buna cevap verdi. stackoverflow.com/questions/28404452/…
Steven Anderson

63

Bunun gibi kimlik doğrulama bilgilerine sahip bir HTTP üstbilgisi eklemek için beforeSend geri aramasını kullanın :

var username = $("input#username").val();
var password = $("input#password").val();  

function make_base_auth(user, password) {
  var tok = user + ':' + password;
  var hash = btoa(tok);
  return "Basic " + hash;
}
$.ajax
  ({
    type: "GET",
    url: "index1.php",
    dataType: 'json',
    async: false,
    data: '{}',
    beforeSend: function (xhr){ 
        xhr.setRequestHeader('Authorization', make_base_auth(username, password)); 
    },
    success: function (){
        alert('Thanks for your comment!'); 
    }
});

4
Burada Base64 şifrelemesi için kullanılan "btoa" nın 10'dan az IE sürümlerinde ve bazı mobil platformlarda desteklenmediğini fark etmelisiniz
SET

1
Ayrıca, buna göre developer.mozilla.org/en-US/docs/DOM/window.btoa sen btoa (çıkış yapılmış (encodeURIComponent (str))) kullanmalıdır
SET

@SET, btoa olması gerektiğini tahmin ediyorum (encodeURIComponent (escape (str)))
Saurabh Kumar

Ben bu yüzden async yanlış kurtulmak ve başarı fonksiyonu sonuç parametresi ekledi yanıt almak istedim. Ayrıca önceden oluşturulmuş Yetkilendirme başlığını da kullandım.
radtek

1
@SET, Base64'in şifreleme olmadığı, kodladığı belirtilmelidir. Şifreleme olsaydı, tek bir işlev çağrısı ile kodunu çözmek çok kolay olmaz
Chris

40

Veya, 1.5'te sunulan headers özelliğini kullanmanız yeterlidir:

headers: {"Authorization": "Basic xxxx"}

Referans: jQuery Ajax API'sı


Lütfen her kullanıcı için nasıl yapılacağını söyler misiniz? Yani veritabanından her kullanıcı için api jetonu almak ve ajax başlığı ile göndermek demek.
Haniye Shadman

32

Yukarıdaki örnekler biraz kafa karıştırıcıdır ve bu muhtemelen en iyi yoldur:

$.ajaxSetup({
  headers: {
    'Authorization': "Basic " + btoa(USERNAME + ":" + PASSWORD)
  }
});

Yukarıdakileri Rico ve Yossi'nin cevabından aldım.

Btoa işlevi Base64 bir dize kodlar.


5
URL'den bağımsız olarak giriş bilgilerini tüm AJAX istekleriyle göndereceğiniz için bu kötü bir fikirdir . Ayrıca, $.ajaxSetup()"Gelecekteki Ajax istekleri için varsayılan değerleri ayarlayın. Kullanılması önerilmez. "
Zero3

27

Diğerlerinin önerdiği gibi, kullanıcı adını ve şifreyi doğrudan Ajax çağrısında ayarlayabilirsiniz:

$.ajax({
  username: username,
  password: password,
  // ... other parameters.
});

VEYA kimlik bilgilerinizi düz metin olarak saklamak istemiyorsanız headers özelliğini kullanın:

$.ajax({
  headers: {"Authorization": "Basic xxxx"},
  // ... other parameters.
});

Hangi yolu gönderirseniz gönderin, sunucunun çok kibar olması gerekir. Apache için .htaccess dosyanızın şöyle görünmesi gerekir:

<LimitExcept OPTIONS>
    AuthUserFile /path/to/.htpasswd
    AuthType Basic
    AuthName "Whatever"
    Require valid-user
</LimitExcept>

Header always set Access-Control-Allow-Headers Authorization
Header always set Access-Control-Allow-Credentials true

SetEnvIf Origin "^(.*?)$" origin_is=$0
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is

Açıklama:

Bazı etki alanları arası istekler için tarayıcı , kimlik doğrulama başlıklarınızı eksik bir ön kontrol OPTIONS isteği gönderir . Kimlik doğrulama yönergelerinizi LimitExcept içine sarınÖn kontrolün doğru şekilde yanıtlanması etiketinin .

Ardından, tarayıcıya kimlik doğrulamasına izin verildiğini ve Access-Control-Allow-Origin'i bildirmek için birkaç üstbilgi gönderin siteler arası istek için .

Bazı durumlarda, * joker karakteri Access-Control-Allow-Origin için bir değer olarak çalışmaz : Callee'nin tam etki alanını döndürmeniz gerekir. Bu değeri yakalamak için SetEnvIf kullanın.


5
Tarayıcıların yetkilendirme başlıkları olmadan bir CORS ön kontrol isteği gönderdiği bilgi için teşekkürler! Bunun gibi detaylar saatlerce hata ayıklamaya neden olabilir!
jbandi

23

Tüm ajax istekleri için varsayılan değerleri ayarlayabilen jQuery ajaxSetup işlevini kullanın .

$.ajaxSetup({
  headers: {
    'Authorization': "Basic XXXXX"
  }
});

11

JSONP temel kimlik doğrulaması ile çalışmaz, bu nedenle jQuery beforeSend geri çağrısı JSONP / Script ile çalışmaz.

İsteğe kullanıcı ve parola ekleyerek bu sınırlamayı aşmayı başardım (örn. User: pw@domain.tld). Bu, Internet Explorer dışında hemen hemen tüm tarayıcılarla çalışır , URL'ler aracılığıyla kimlik doğrulamanın desteklenmediği (çağrı gerçekleştirilmez).

Bkz. Http://support.microsoft.com/kb/834489 .


güvenlik açısından bilge buna izin vermemek akıllıca bir seçim
George Birbilis

Bağlantı kopmuş (404).
Peter Mortensen

10

Bunu aşağıda gösterildiği gibi başarmanın 3 yolu vardır.

Yöntem 1:

var uName="abc";
var passwrd="pqr";

$.ajax({
    type: '{GET/POST}',
    url: '{urlpath}',
    headers: {
        "Authorization": "Basic " + btoa(uName+":"+passwrd);
    },
    success : function(data) {
      //Success block  
    },
   error: function (xhr,ajaxOptions,throwError){
    //Error block 
  },
});

Yöntem 2:

var uName="abc";
var passwrd="pqr";

$.ajax({
    type: '{GET/POST}',
    url: '{urlpath}',
     beforeSend: function (xhr){ 
        xhr.setRequestHeader('Authorization', "Basic " + btoa(uName+":"+passwrd)); 
    },
    success : function(data) {
      //Success block 
   },
   error: function (xhr,ajaxOptions,throwError){
    //Error block 
  },
});

Yöntem 3:

var uName="abc";
var passwrd="pqr";

$.ajax({
    type: '{GET/POST}',
    url: '{urlpath}',
    username:uName,
    password:passwrd, 
    success : function(data) {
    //Success block  
   },
    error: function (xhr,ajaxOptions,throwError){
    //Error block 
  },
});

8

SharkAlley cevabına göre nginx ile de çalışıyor.

Ben nginx arkasında bir sunucudan jQuery tarafından veri almak ve Base Auth tarafından kısıtlanmış bir çözüm arıyorlardı. Bu benim için çalışıyor:

server {
    server_name example.com;

    location / {
        if ($request_method = OPTIONS ) {
            add_header Access-Control-Allow-Origin "*";
            add_header Access-Control-Allow-Methods "GET, OPTIONS";
            add_header Access-Control-Allow-Headers "Authorization";

            # Not necessary
            #            add_header Access-Control-Allow-Credentials "true";
            #            add_header Content-Length 0;
            #            add_header Content-Type text/plain;

            return 200;
        }

        auth_basic "Restricted";
        auth_basic_user_file /var/.htpasswd;

        proxy_pass http://127.0.0.1:8100;
    }
}

Ve JavaScript kodu:

var auth = btoa('username:password');
$.ajax({
    type: 'GET',
    url: 'http://example.com',
    headers: {
        "Authorization": "Basic " + auth
    },
    success : function(data) {
    },
});

Yararlı bulduğum makale:

  1. Bu konunun cevapları
  2. http://enable-cors.org/server_nginx.html
  3. http://blog.rogeriopvl.com/archives/nginx-and-the-http-options-method/
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.