2013-07-31 4 views
36

Come posso ottenere un'autenticazione di base funzionante in AngularJs? Ho cercato su Google e le risorse non funzionano per me. Sono molto nuovo a AngularJSCome faccio a ottenere l'autenticazione di base su angularjs?

+12

Se pensi che la mia domanda faccia schifo, nota che l'ho appena chiesto in modo che potessi rispondere. Mi ci è voluto più di un'ora per capire e non volevo che qualcun altro dovesse spendere lo sforzo. –

risposta

54

Assumendo che il codice HTML è definita in questo modo:

<!doctype html> 
<html ng-app="sandbox-app"> 
<head> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> 
    <script src="todo.js"></script> 
    <link rel="stylesheet" href="todo.css"> 
</head> 
<body> 
<h2>Todo</h2> 
<div ng-controller="TodoCtrl"> 
    <ol> 
... 
    </ol> 
</div> 
</body> 
</html> 

È possibile rendere il backend connettersi a un API REST utilizzando autenticazione di base come questo:

var app = angular.module('sandbox-app', []); 
app.config(function($httpProvider) { 

}); 

app.factory('Base64', function() { 
    var keyStr = 'ABCDEFGHIJKLMNOP' + 
      'QRSTUVWXYZabcdef' + 
      'ghijklmnopqrstuv' + 
      'wxyz/' + 
      '='; 
    return { 
     encode: function (input) { 
      var output = ""; 
      var chr1, chr2, chr3 = ""; 
      var enc1, enc2, enc3, enc4 = ""; 
      var i = 0; 

      do { 
       chr1 = input.charCodeAt(i++); 
       chr2 = input.charCodeAt(i++); 
       chr3 = input.charCodeAt(i++); 

       enc1 = chr1 >> 2; 
       enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 
       enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 
       enc4 = chr3 & 63; 

       if (isNaN(chr2)) { 
        enc3 = enc4 = 64; 
       } else if (isNaN(chr3)) { 
        enc4 = 64; 
       } 

       output = output + 
         keyStr.charAt(enc1) + 
         keyStr.charAt(enc2) + 
         keyStr.charAt(enc3) + 
         keyStr.charAt(enc4); 
       chr1 = chr2 = chr3 = ""; 
       enc1 = enc2 = enc3 = enc4 = ""; 
      } while (i < input.length); 

      return output; 
     }, 

     decode: function (input) { 
      var output = ""; 
      var chr1, chr2, chr3 = ""; 
      var enc1, enc2, enc3, enc4 = ""; 
      var i = 0; 

      // remove all characters that are not A-Z, a-z, 0-9, +, /, or = 
      var base64test = /[^A-Za-z0-9\+\/\=]/g; 
      if (base64test.exec(input)) { 
       alert("There were invalid base64 characters in the input text.\n" + 
         "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" + 
         "Expect errors in decoding."); 
      } 
      input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 

      do { 
       enc1 = keyStr.indexOf(input.charAt(i++)); 
       enc2 = keyStr.indexOf(input.charAt(i++)); 
       enc3 = keyStr.indexOf(input.charAt(i++)); 
       enc4 = keyStr.indexOf(input.charAt(i++)); 

       chr1 = (enc1 << 2) | (enc2 >> 4); 
       chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 
       chr3 = ((enc3 & 3) << 6) | enc4; 

       output = output + String.fromCharCode(chr1); 

       if (enc3 != 64) { 
        output = output + String.fromCharCode(chr2); 
       } 
       if (enc4 != 64) { 
        output = output + String.fromCharCode(chr3); 
       } 

       chr1 = chr2 = chr3 = ""; 
       enc1 = enc2 = enc3 = enc4 = ""; 

      } while (i < input.length); 

      return output; 
     } 
    }; 
}); 

//here's where YOUR code is finally accessed 
function TodoCtrl($scope, $http, Base64) { 

    $http.defaults.headers.common = {"Access-Control-Request-Headers": "accept, origin, authorization"}; //you probably don't need this line. This lets me connect to my server on a different domain 
    $http.defaults.headers.common['Authorization'] = 'Basic ' + Base64.encode('admin' + ':' + 'abc12345'); 
    $http({method: 'GET', url: 'http://localhost:8888/app/api/v1/pets'}). 
      success(function(data, status, headers, config) { 
       $scope.pets = data; 
       // this callback will be called asynchronously 
       // when the response is available 
      }). 
      error(function(data, status, headers, config) { 
       alert(data); 
       // called asynchronously if an error occurs 
       // or server returns response with an error status. 
      }); 

} 

Nota la maggior parte di questo codice è il metodo Base64. Se non è necessario sostenere IE9 e inferiore, si potrebbe sostituirlo con implementazioni native JS - atob() e btoa(): https://developer.mozilla.org/en/docs/web/api/windowbase64/atob


Per me, questo riporta sempre una 401 prima che funziona realmente. Credo che questo sia un bug con il codice angolare, ma non ne sono sicuro. Ho creato un problema qui: https://github.com/angular/angular.js/issues/3406

+9

non preoccuparti, a volte ci sono persone annoiate che fanno a caso roba a caso. –

+2

Sembra che tu stia correndo nel caso in cui il tuo server non risponda correttamente alla richiesta di verifica preliminare CORS. Puoi mostrare la parte in cui il tuo server risponde alle due richieste (la richiesta OPTIONS e il GET effettivo)? –

+10

Inoltre, se non sei preoccupato per Siyfion