AngularJS+Spring Security使用基本身份驗證

這篇文章演示AngularJS應用程序如何消耗REST API,它使用Spring Security的基本身份驗證。

Secure Spring REST API使用基本身份驗證這篇文章中演示瞭如何使用Spring Security基本身份驗證細節。 這個應用程序將作爲這個例子的後端。雖然我們只在這裏接觸到一些主要概念,對於後端完整的代碼不會在這裏再重複。所以您可以自行下載,安裝並在本地啓動,以便測試這個AngularJS應用程序。

這裏我們將主要集中在前端功能,這是一個純粹的AngularJS應用程序,它能與REST API有很好地通信。現在訪問: http://localhost:8080/AngularClientWithBasicAuth/ 

AngularJS+Spring

什麼是基本身份驗證?

如基於Web的客戶端的登錄頁面或會話身份驗證的傳統方法與人類有良好的互動效果,但並不能完全適合很好地應用,[REST]客戶端它不止只一個Web應用程序進行通信時。考慮它是一個完全不同於服務器上的其他API,它隨時都會與服務器的API通信,無需任何人爲干預。

基本身份驗證它提供了一個方法來解決這個問題,雖然不是很安全。基本身份驗證,客戶端的每個請求發送Base64編碼憑據,使用HTTP[授權]頭。這意味着每個請求獨立於其他請求和服務器可能/不維護客戶端,這對可擴展性是非常好的。

前端部分

1.每個請求使用AngularJS發送Authorization頭

由於認證頭需要在每個請求時發送,攔截器是一個不錯的選擇用來處理這些請求,而不用手動指定所有 $HTTP頭的方法。

authInterceptor.js

angular.module('myApp')
.factory('AuthInterceptor', [function() {
return {
// Send the Authorization header with each request
'request': function(config) {
config.headers = config.headers || {};
var encodedString = btoa("bill:abc123");
config.headers.Authorization = 'Basic '+encodedString;
return config;
}
};
}]);

請注意:我們如何使用 btoa() 函數來獲得用戶的Base64編碼字符串的憑據。這就是我們需要啓用基本身份驗證。應用程序的其餘部分是典型的與服務器REST API通信的AngularJS應用程序。現在,這個攔截器需要使用AngularJS註冊,如下圖所示。

2. 應用程序

app.js

'use strict';

var App = angular.module('myApp',[]);

App.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('AuthInterceptor');
}]);

3. 服務與服務器上的REST API通信

由於攔截器,服務被單獨管理,以下服務不涉及任何安全相關的東西。

UserService.js

'use strict';

angular.module('myApp').factory('UserService', ['$http', '$q', function($http, $q){

var REST\_SERVICE\_URI = 'http://localhost:8080/SecureRESTApiWithBasicAuthentication/user/';

var factory = {
    fetchAllUsers: fetchAllUsers,
    createUser: createUser,
    updateUser:updateUser,
    deleteUser:deleteUser
};

return factory;

function fetchAllUsers() {
    var deferred = $q.defer();
    $http.get(REST\_SERVICE\_URI)
        .then(
        function (response) {
            deferred.resolve(response.data);
        },
        function(errResponse){
            console.error('Error while fetching Users');
            deferred.reject(errResponse);
        }
    );
    return deferred.promise;
}

function createUser(user) {
    var deferred = $q.defer();
    $http.post(REST\_SERVICE\_URI, user)
        .then(
        function (response) {
            deferred.resolve(response.data);
        },
        function(errResponse){
            console.error('Error while creating User');
            deferred.reject(errResponse);
        }
    );
    return deferred.promise;
}


function updateUser(user, id) {
    var deferred = $q.defer();
    $http.put(REST\_SERVICE\_URI+id, user)
        .then(
        function (response) {
            deferred.resolve(response.data);
        },
        function(errResponse){
            console.error('Error while updating User');
            deferred.reject(errResponse);
        }
    );
    return deferred.promise;
}

function deleteUser(id) {
    var deferred = $q.defer();
    $http.delete(REST\_SERVICE\_URI+id)
        .then(
        function (response) {
            deferred.resolve(response.data);
        },
        function(errResponse){
            console.error('Error while deleting User');
            deferred.reject(errResponse);
        }
    );
    return deferred.promise;
}

}]);

4. 控制器

user_controller.js

'use strict';

angular.module('myApp').controller('UserController', ['$scope', 'UserService', function($scope, UserService) {
var self = this;
self.user={id:null,username:'',address:'',email:''};
self.users=[];

self.submit = submit;
self.edit = edit;
self.remove = remove;
self.reset = reset;


fetchAllUsers();

function fetchAllUsers(){
    UserService.fetchAllUsers()
        .then(
        function(d) {
            self.users = d;
        },
        function(errResponse){
            console.error('Error while fetching Users');
        }
    );
}

function createUser(user){
    UserService.createUser(user)
        .then(
        fetchAllUsers,
        function(errResponse){
            console.error('Error while creating User');
        }
    );
}

function updateUser(user, id){
    UserService.updateUser(user, id)
        .then(
        fetchAllUsers,
        function(errResponse){
            console.error('Error while updating User');
        }
    );
}

function deleteUser(id){
    UserService.deleteUser(id)
        .then(
        fetchAllUsers,
        function(errResponse){
            console.error('Error while deleting User');
        }
    );
}

function submit() {
    if(self.user.id===null){
        console.log('Saving New User', self.user);
        createUser(self.user);
    }else{
        updateUser(self.user, self.user.id);
        console.log('User updated with id ', self.user.id);
    }
    reset();
}

function edit(id){
    console.log('id to be edited', id);
    for(var i = 0; i < self.users.length; i++){
        if(self.users\[i\].id === id) {
            self.user = angular.copy(self.users\[i\]);
            break;
        }
    }
}

function remove(id){
    console.log('id to be deleted', id);
    if(self.user.id === id) {//clean form if the user to be deleted is shown there.
        reset();
    }
    deleteUser(id);
}


function reset(){
    self.user={id:null,username:'',address:'',email:''};
    $scope.myForm.$setPristine(); //reset Form
}

}]);

5. 視圖

index.html

Form Demo