此问题涉及angular-app项目及其对用户进行身份验证的方式。
原始实现通过在路由器上使用resolve子句来保护对某些URL的访问。这看起来像:
$routeProvider.when('/projects', {
templateUrl:'projects/projects-list.tpl.html',
controller:'ProjectsViewCtrl',
resolve:{
projects:['Projects', function (Projects) {
//TODO: fetch only for the current user
return Projects.all();
}],
authenticatedUser: securityAuthorizationProvider.requireAuthenticatedUser
}
});
在对用户进行身份验证并获取项目(以防止ui闪烁)之前,不会呈现视图。如果未对用户进行身份验证,则弹出登录弹出窗口,在用户提交后,将解析承诺并显示请求的页面。如果Projects.all()调用不需要auth,这很好用。
这是服务器调用的日志:
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:47 GMT] "GET /projects HTTP/1.1" 200 739 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
Unauthenticated
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:47 GMT] "GET /current-user HTTP/1.1" 200 24 "http://localhost:3000/projects" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
Unauthenticated
Unauthenticated
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:47 GMT] "GET /current-user HTTP/1.1" 200 24 "http://localhost:3000/projects" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:47 GMT] "GET /databases/angular_app/collections/projects?q=%7B%7D HTTP/1.1" 200 10 "http://localhost:3000/projects" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
Unauthenticated
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:59 GMT] "POST /login HTTP/1.1" 200 161 "http://localhost:3000/projects" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
对angular_app / collections / projects的调用即使对于未经身份验证的用户也是有效的。
在我的情况下,我有以下代码:
$stateProvider
.state('root.tickets', {
url: '/tickets',
views: {
'container@': {
templateUrl: 'tickets/tickets-list.tpl.html',
controller:'TicketsViewCtrl',
resolve:{
ticketsy: ['Restangular', function (Restangular) {
//Call to tickets must be authenticated
return Restangular.all('tickets').getList();
}],
authenticatedUser: securityAuthorizationProvider.requireAuthenticatedUser
}
}
}
差异是(除了我使用ui-router和Restangular),api调用必须经过身份验证。服务器日志如下所示:
[28/Oct/2013 05:50:15] "GET /api/tickets/ HTTP/1.1" 403 59
[28/Oct/2013 05:50:15] "GET / HTTP/1.1" 200 963
[28/Oct/2013 05:50:16] "GET /api/current-user/ HTTP/1.1" 200 14
[28/Oct/2013 05:50:16] "GET /api/tickets HTTP/1.1" 301 0
[28/Oct/2013 05:50:16] "GET /api/tickets/ HTTP/1.1" 403 59
[28/Oct/2013 05:50:22] "POST /api/login/ HTTP/1.1" 200 120
注意这里的403状态代码。效果是用户看到登录弹出窗口,进行身份验证,然后看到空白页面。我想这是因为数据提取失败。
我的问题是 - 是否有可能强迫承诺的顺序?我想首先检查用户是否经过身份验证,然后向后端发出呼叫等。或者,我可以在此处使用其他任何解决方案吗?我正在学习Angular,所以即使有一个简单的解决方案,对我来说也不是很明显。
答案 0 :(得分:15)
我喜欢使用解析器模式,但发现在角度ui路由器中执行这些类型的操作非常困难。
一个解决方案是依赖将authenticatedUser解析器的结果注入您想要保护的api调用解析器,如:
$stateProvider
.state('root.tickets', {
url: '/tickets',
views: {
'container@': {
templateUrl: 'tickets/tickets-list.tpl.html',
controller:'TicketsViewCtrl',
resolve:{
authenticatedUser: securityAuthorizationProvider.requireAuthenticatedUser,
ticketsy: function (Restangular, authenticatedUser) {
//Call to tickets must be authenticated
return Restangular.all('tickets').getList();
}
}
}
}
这样,解析器将在链中运行(authenticatedUser - > ticketsy),而不是一次性异步。
我希望这有所帮助..希望有更好的方法来实现它...这就是为什么我要搜索堆栈溢出。
答案 1 :(得分:0)
你有没有试过这样的东西。
return securityAuthorizationProvider.requireAuthenticatedUser().then(function() {
return Restangular.all('tickets').getList();
});
基本上requireAuthenticatedUser
会返回一个承诺,因此您可以通过调用Restangular调用来链接它。