我有一个使用 Play + AngularJS构建的简单应用程序,它需要在访问大多数路由之前进行身份验证。登录流程包括“记住我”功能,该功能将会话 ID 存储到浏览器本地存储中,并在用户返回应用程序时映射到服务器端的有效授权数据库会话条目。
我遇到的问题是我在模块的run() 函数中进行了会话检查(提取 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 并且它似乎没有什么不同(也许运行函数不兑现承诺)。我一直是在$routeProviderresolve
中使用功能的顾问,但我不知道该怎么做,而且我对必须为每条路线都添加它并不感到非常兴奋。
我认为这是一个非常常见的用例,并且每天都会得到解决。希望有人能给我一些关于我的代码的指导,或者分享他们“记住我”和 AngularJS 的方法。