web-dev-qa-db-fra.com

Utiliser l'authentification de base avec jQuery et Ajax

J'essaie de créer une authentification de base via le navigateur, mais je ne peux pas vraiment y arriver.

Si ce script ne sera pas là, l'authentification du navigateur prendra le relais, mais je souhaite informer le navigateur que l'utilisateur est sur le point de procéder à l'authentification.

L'adresse devrait être quelque chose comme:

http://username:[email protected]/

J'ai un formulaire:

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

Et un script:

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!');
    }
});
396
Patrioticcow

Utilisez le rappel beforeSend de jQuery pour ajouter un en-tête HTTP contenant les informations d'authentification:

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

Comment les choses changent en un an. En plus de l'attribut d'en-tête à la place de xhr.setRequestHeader, jQuery actuel (1.7.2+) inclut un attribut nom d'utilisateur et mot de passe avec l'appel $.ajax.

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

EDIT de commentaires et autres réponses: Pour être clair - afin d’envoyer de manière préemptive une authentification sans réponse 401 Unauthorized, au lieu de setRequestHeader (pre -1.7), utilisez 'headers':

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

Utilisez le beforeSend callback pour ajouter un en-tête HTTP contenant les informations d'authentification, comme suit:

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!'); 
    }
});
61
Adrian Toman

Ou utilisez simplement la propriété headers introduite dans 1.5:

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

Référence: API jQuery Ajax

40
AsemRadhwi

Les exemples ci-dessus sont un peu déroutants et c’est probablement le meilleur moyen:

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

J'ai pris ce qui précède d'une combinaison des réponses de Rico et de Yossi.

La fonction btoaBase64 code une chaîne.

31
Paul Odeon

Comme d'autres l'ont suggéré, vous pouvez définir le nom d'utilisateur et le mot de passe directement dans l'appel Ajax:

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

OU utilisez la propriété headers si vous préférez ne pas stocker vos informations d'identification en texte brut:

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

Quelle que soit la manière dont vous l'envoyez, le serveur doit être très poli. Pour Apache, votre fichier .htaccess devrait ressembler à ceci:

<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

Explication:

Pour certaines requêtes interdomaines, le navigateur envoie une requête de contrôle en amont OPTIONS sans en-têtes d’authentification. Enveloppez vos directives d'authentification à l'intérieur de la balise LimitExcept pour répondre correctement au contrôle en amont.

Envoyez ensuite quelques en-têtes pour indiquer au navigateur qu'il est autorisé à s'authentifier, ainsi que Access-Control-Allow-Origin pour autoriser la requête intersite.

Dans certains cas, le caractère générique * ne fonctionne pas en tant que valeur pour Access-Control-Allow-Origin: Vous devez renvoyer le domaine exact de l'appelé. Utilisez SetEnvIf pour capturer cette valeur.

26
SharkAlley

Utilisez la fonction jQuery ajaxSetup , qui permet de définir les valeurs par défaut pour toutes les demandes ajax.

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

JSONP ne fonctionne pas avec l'authentification de base, donc le rappel jQuery beforeSend ne fonctionnera pas avec JSONP/Script.

J'ai réussi à contourner cette limitation en ajoutant l'utilisateur et le mot de passe à la demande (par exemple, utilisateur: [email protected]). Cela fonctionne avec à peu près tous les navigateurs à l'exception d'Internet Explorer où l'authentification par le biais d'URL n'est pas prise en charge (l'appel ne sera tout simplement pas exécuté).

Voir http://support.Microsoft.com/kb/834489 .

11
arnebert

Selon SharkAlley, cela fonctionne aussi avec nginx.

J'étais à la recherche d'une solution pour obtenir des données par jQuery à partir d'un serveur situé derrière nginx et restreint par Base Auth. Cela fonctionne pour moi:

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

Et le code JavaScript est:

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

Article que je trouve utile:

  1. Les réponses de ce sujet
  2. http://enable-cors.org/server_nginx.html
  3. http://blog.rogeriopvl.com/archives/nginx-and-the-http-options-method/
8
Max

Il y a 3 façons d'y parvenir, comme indiqué ci-dessous

Méthode 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 
  },
});

Méthode 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 
  },
});

Méthode 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 
  },
});
5
GSB