我們正在使用AngularJS和Ionic框架創建基於PhoneGap的應用程序。AngularJS回調流程
這個應用程序是一個商店管理系統,它使用OAuth2與現有的網絡應用程序綁定。
該應用程序包含一個'訂單'視圖,顯示客戶收到的訂單列表。在加載訂單列表之前,以下函數將驗證用戶的訪問令牌是否仍然有效,如果沒有,則獲取新令牌。
function verifyAccessToken() {
var now = new Date().getTime();
if (now > tokenStore.access_token_expiry_date) {
// renew access token
$http({
url: '*API URL*/token',
method: "POST",
data: {
refresh_token : tokenStore.refresh_token,
grant_type : 'refresh_token',
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectURI
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
})
.success(function (data, status, headers, config) {
tokenStore['access_token'] = data.access_token;
var expiresAt = now + parseInt(data.expires_in, 10) * 1000 - 10000;
tokenStore['access_token_expiry_date'] = expiresAt;
console.log(data.access_token);
})
.error(function (data, status, headers, config) {
if(status=='404') {
$rootScope.$emit('serviceUnavailable');
}
if(status=='400' || status=='401') {
$rootScope.$emit('tokenUnauthorized');
}
console.log(status);
console.log(data);
});
}
};
然後調用使用新的訪問令牌
return $http({method: 'GET', url: '*API URL*?access_token=' + tokenStore.access_token, params: {}})
.error(function(data, status, headers, config) {
if(status=='404') {
$rootScope.$emit('serviceUnavailable');
}
if(status=='401') {
$rootScope.$emit('tokenUnauthorized');
}
console.log(status);
console.log(data);
});
}
問題的命令列表是在HTTP GET不等待VerifyAccessToken功能來完成。
這是如何構建的,以避免這個問題?
任何意見,你可以提供將不勝感激。
更新2(後klyd的答案):
我在更新了兩個功能OAuth的angular.js描述如下:
的verifyAccessToken函數現在如下:
function verifyAccessToken() {
var deferred = $q.defer();
if ((new Date().getTime()) < tokenStore.access_token_expiry_date) {
/* token is still valid, resolve the deferred and bail early */
deferred.resolve();
return deferred.promise;
}
/* token is not valid, renew it */
alert('getting new access token')
$http({
url: 'https://' + tokenStore.site_name + '.somedomain.com/api/oauth2/token',
method: "POST",
data: {
refresh_token : tokenStore.refresh_token,
grant_type : 'refresh_token',
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectURI
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
}).success(function (data, status, headers, config) {
tokenStore['access_token'] = data.access_token;
var now = new Date().getTime();
var expiresAt = now + parseInt(data.expires_in, 10) * 1000 - 10000;
tokenStore['access_token_expiry_date'] = expiresAt;
console.log(data.access_token);
deferred.resolve();
})
.error(function (data, status, headers, config) {
if(status=='404') {
$rootScope.$emit('serviceUnavailable');
}
if(status=='400' || status=='401') {
$rootScope.$emit('tokenUnauthorized');
}
console.log(status);
console.log(data);
deferred.reject(); // as the last step, reject the deferred, there was a failure
});
return deferred.promise;
}
和getOrders函數現在讀取如下:
執行功能getOrders時function getOrders() {
verifyAccessToken().then(
function() {
return $http({method: 'GET', url: 'https://' + tokenStore.site_name + '.somedomain.com/api/1.0/orders?access_token=' + tokenStore.access_token, params: {}})
.error(function(data, status, headers, config) {
if(status=='404') {
$rootScope.$emit('serviceUnavailable');
}
if(status=='401') {
$rootScope.$emit('tokenUnauthorized');
}
console.log(status);
console.log(data);
});
},
function() {
/* code to handle a failure of renewing the token */
});
}
我controllers.js文件現在引發以下錯誤。
類型錯誤:無法讀取此之前,沒有任何問題工作的不確定
.controller('OrdersCtrl', function ($scope, $stateParams, oauth, $ionicLoading) {
function loadOrders() {
$scope.show();
oauth.getOrders()
.success(function (result) {
$scope.hide();
$scope.orders = result;
console.log(result);
// Used with pull-to-refresh
$scope.$broadcast('scroll.refreshComplete');
})
.error(function(data) {
$scope.hide();
});
}
})
財產 '成功'。有什麼想法嗎?
你還沒有完全發佈足夠的代碼呢。例如,「verifyAccessToken」在哪裏實際調用?它在哪裏定義 - 它有$ http/$ rootScope,但沒有直接注入,是在關閉?你能把一個簡化的jsFiddle或plunkr放在一起來說明這個機制嗎?你也應該再次查看我的例子,你聲明瞭延遲變量,但不對它做任何事情。 – klyd 2014-09-04 11:40:51
對不起 - 漫長的一天。我已經更新了上面的代碼,希望現在更有意義 – 2014-09-04 20:52:19
你快到了。看看你的'getOrders'函數,它不會立即返回任何東西,這就是爲什麼沒有'成功'方法。你需要返回'getOrders'中的'verifyAccessToken()'行。之後,你需要從'.success'和'.error'改變爲'.then'的調用(錯誤和成功是'HttpPromise'的特殊功能)。 – klyd 2014-09-04 21:27:33