2014-10-29 63 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