Tôi đã tạo trang web AngularJS hoạt động với API. API này cung cấp một số tính năng như xác thực (Oauth).Vòng lặp vô hạn trong thiết bị chặn
Khi API trả về lỗi 401, điều đó có nghĩa là access_token
đã hết hạn và cần được làm mới với refresh_token
.
Tôi đã tạo một trình chặn trong AngularJS. Mục tiêu của nó là để kiểm tra xem kết quả trả về bởi API có phải là lỗi 401 hay không và nếu đúng như vậy, nó phải làm mới mã thông báo và sau đó, xử lý yêu cầu bị từ chối trước đó.
Vấn đề là máy đánh chặn tạo ra một vòng lặp vô hạn. Sau sự thất bại thứ hai của yêu cầu ban đầu, nó sẽ dừng lại nhưng không.
angular.module('myApp')
.factory('authInterceptor', function ($rootScope, $q, $window, $injector) {
return {
// If the API returns an error
'responseError' : function(rejection) {
// If it's a 401
if (rejection.status == 401) {
var deferred = $q.defer();
$injector.get('$http').post('http://my-api.local/api/oauth/token', {
grant_type : 'refresh_token',
client_id : 'id',
client_secret : 'secret',
refresh_token : $window.sessionStorage.refresh_token
}, {
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("&");
}
})
// New token request successfull
.success(function(refreshResponse) {
// Processing the failed request again (should fail again because I didn't saved the new tokens)
$injector.get('$http')(rejection.config).success(function(data) {
deferred.resolve(data);
})
.error(function(error, status) {
deferred.reject();
});
return deferred.promise();
})
// New token request failure
.error(function(error, status) {
deferred.reject();
// $location.path('users/login');
return;
});
}
// If it's another errorenter code here
else
return rejection;
}
}
});
Vì vậy, mã này:
- Bắt đầu khi yêu cầu đầu tiên thất bại
- Làm mới token
- Retry yêu cầu nhưng thất bại một lần nữa (< - Tôi chỉ muốn làm cho nó dừng lại ở đây)
- Làm mới mã thông báo
- Thử lại yêu cầu nhưng không thành công lại
- Làm mới token
- Retry yêu cầu nhưng thất bại một lần nữa
- vv ...
điều này không đúng: 'return deferred.promise();'. Bạn chỉ nên trả về đối tượng lời hứa 'return deferred.promise' và không cố thực thi nó. – user2943490