我有一个simple app I'm building使用Play + AngularJS,需要进行身份验证才能访问大多数路由。登录流程包括"记住我"将会话ID存储到浏览器本地存储中的功能,并在用户返回应用程序时映射到服务器端的有效授权数据库会话条目。
我遇到的问题是我在模块的run() function中进行会话检查(提取cookie并与服务器进行比较):
.run(function ($rootScope, $http, $cookieStore, $location) {
// <snip>
// check if there is already a session?
var sessionId = window.localStorage["session.id"];
if (sessionId == null) {
sessionId = $cookieStore.get("session.id");
}
if (sessionId != null) {
$http.get("/sessions/" + sessionId)
.success(function (data) {
$http.defaults.headers.common['X-Session-ID'] = data.id;
$cookieStore.put("session.id", data.id);
$rootScope.user = data.user;
})
.error(function () {
// remove the cookie, since it's dead
$cookieStore.remove("session.id");
window.localStorage.removeItem("session.id");
$location.path("/login");
});
} else {
if ($location.path() != "/login" && $location.path() != "/signup") {
$location.path("/login");
}
}
});
问题是这个函数执行一个AJAX调用,我不知道会话在完成之前是否有效。但是,加载的控制器(通过$ routeProvider选择的路由)可以触发另一个AJAX调用,该调用通常在另一个完成之前启动,从而导致竞争条件和初始请求获得401响应代码。
所以我的问题是:如何在应用程序的任何其他部分运行之前强制运行(及其关联的$ http调用)?我在这里尝试过使用$ q / promise,它似乎没有什么区别(也许运行函数不会兑现承诺)。我已经成为$routeProvider使用resolve
功能的顾问,但我不确切地知道该做什么,而且我并不是因为不得不把它放在每个人身上而感到非常高兴。无论如何,路线。
我认为这是一个非常常见的用例,它每天都会得到解决。希望有人可以给我一些方向,或者分享他们的方法,以便记住我&#34;和AngularJS。
答案 0 :(得分:0)
您需要在从服务器获取会话后手动引导您的应用程序。如果您使用jQuery就可以轻松实现,或者即使没有jQuery,您也可以使用注入器在引导之前访问$ http
$.get(server,function(){
//success , set variable.
}).fail(function (){
//failed :( redirect to login or set session to false etc... null
})
.always(function(){
//alwyas bootstrap in both case and set result as a constant or variable Angular.module('app').variable('session',sessionResult);
});
我现在正在打电话,但这应该给你一个想法