2014-10-29 64 views
2

當前,我正在實現一個完全無狀態的基於令牌的身份驗證,使用AngularJS和REST API作爲後端服務。這很有效,但關於一個我目前不知道的狀態,並想問你如何處理它。使用應用程序級別解析的動態指令模板AngularJS

我的目的只是將我的身份驗證令牌保存在客戶端的本地存儲中。在從應用程序初始加載時,我想從REST API(GET/me)中檢索所有用戶信息,並將其保存在我的AngularJS項目的$ scope中。

實施它後,我有幾個問題,以確保檢索到的用戶信息已完全解決,並可以使用信息(如來自用戶的訪問權限)。

我只是想讓你展示一個例子,我遇到了一種「異步問題」。

angular.directive('myDirective', ['MyAsyncService', function(MyAsyncService) { 
    return { 
    restrict: 'E', 
    templateUrl: function(element, attributes) { 
     console.log(MyAsyncService.getData()); 
    } 
    } 
}] 

在這個例子中,當呈現指令時,我的異步服務還沒有信息。還從ngRoute/ui-router或AngularJS的run()方法中檢索解析函數中的異步數據無法解決我的問題。

所以回到我的問題...最好從客戶端的用戶保存一些信息,以避免一些這樣的問題?從我的角度來看,最好不要保存任何類型的用戶信息(如訪問權限,用戶名,ID,電子郵件地址等),以達到安全目的。

如何處理基於令牌的AngularJS應用程序中的身份驗證和授權?

在此先感謝您,希望您能回到正軌。

+1

對不起,我聽不懂你的問題1通過做這樣的事情模板上。如果你能解釋更多一點! – 2014-11-04 12:56:00

+0

我會盡力詳細解釋我的意圖。在我的用戶登錄我的AngularJS應用程序後,我將從我的REST API服務生成的令牌保存在客戶端的本地存儲中。 之後,我可以通過我的API端點/我獲取所有用戶信息 - 這種方式和預期的一樣。問題是,我不想保存除客戶端本地存儲中的身份驗證令牌之外的任何用戶信息。因此,在引導我的應用程序後,我調用/ me端點並將響應(完整用戶對象)保存在我的範圍中。 – xyNNN 2014-11-05 00:09:44

+0

問題是,這個異步調用是在我的angularjs指令呈現之後執行的。但在我的指令中,我需要來自用戶對象(我保存在範圍內)的一些信息,如accessRoles,但從邏輯上來說,當我嘗試從$ scope.user中獲取某些信息時會得到一個未定義的信息,因爲異步調用已完成。希望這可以清楚你的看法。在此先感謝 – xyNNN 2014-11-05 00:14:00

回答

2

您需要resolve()身份驗證 - 尤其是應用程序級別的此類身份驗證。如果你不使用ui.router - 請看看。

當我們在一條路線上resolve()我們所說的是 - 在這件事完成之後,別做任何事。

這也假定您熟悉承諾

您的解決方案依賴性最終會期望這個異步請求正在返回一個承諾,以便在回調完成執行後可以鏈接控制器邏輯。

例如:

$stateProvider 
    .state('myState', { 
    resolve:{ 
     auth: function($http){ 
     // $http returns a promise for the url data 
     return $http({method: 'GET', url: '/myauth'}); 
     } 
    }, 
    controller: function($scope, auth){ 
     $scope.simple = auth; 
    } 
}); 

但還有更多。如果你想決心在應用程序執行的任何路線的開頭髮生 - 你還需要鏈中的狀態聲明:

$stateProvider 
    .state('app', { 
    abstract: true, 
    templateUrl: 'app/views/app.tpl.html', 
    resolve:{ 
     auth: function($http){ 
     // $http returns a promise for the url data 
     return $http({method: 'GET', url: '/myauth'}); 
     } 
    }, 
    controller: function($scope, auth){ 
     $scope.resolvedauth = auth; 
    } 
    } 
    .state('app.home', { 
    url: '/home', 
    templateUrl: 'home/views/home.tpl.html', 
    controller: function($scope){ 
     //Should be available. 
     console.log($scope.$parent.resolvedauth); 
    } 
    }); 

現在,你的孩子從應用層面的決心繼承,你可以控制

.directive('myDirective', function() { 
    return { 
    templateUrl: function(elem, attr){ 
     return 'myDirective.'+attr.auth+'.html'; 
    } 
    }; 
}); 

而且聲明本身:

<my-directive auth="resolvedauth.status" /> 
+0

感謝您的解決方案,特別是我目前使用的這種方式呢。問題是,即使解析了ui-router/ngRoute的解析函數,該指令也是呈現出來的。 根據用戶狀態我想強制我的指令顯示另一個模板。問題是,在執行僞指令的「templateUrl」函數時,異步認證調用沒有完成。我可以解決這個問題,當我只使用一個模板並用「ng-show」控制模板時,但我認爲這不是乾淨的方式......你知道我的意思嗎? – xyNNN 2014-11-05 05:44:41

+0

你能理解我的打算嗎?也許有可能我可以在每個請求中使用HTTP Interceptor來解決它,以檢查用戶是否已通過身份驗證,如果是,請檢索用戶對象並繼續執行引導。然後我的指令應該在我的用戶對象在$ rootScope – xyNNN 2014-11-05 11:27:10

+0

好例子中可用之後呈現。我想指出的是,使用$ scope。$ parent引用resolvedauth是不必要的,因爲範圍使用原型繼承。您可以輕鬆使用$ scope.resolvedauth。 – kmkemp 2014-11-06 20:51:29