Zrobiłem stronę AngularJS pracującą z interfejsem API. Ten interfejs API udostępnia kilka funkcji, takich jak uwierzytelnianie (Oauth).Nieskończona pętla w przechwytywaczu
Gdy interfejs API zwraca błąd 401, oznacza to, że access_token
wygasł i należy go odświeżać za pomocą refresh_token
.
Stworzyłem przechwytujący w AngularJS. Jego celem jest sprawdzenie, czy wynik zwrócony przez interfejs API to błąd 401, a jeśli tak, to musi odświeżyć token, a następnie przetworzyć poprzednie odrzucone żądanie.
Problem polega na tym, że przechwytujący tworzy nieskończoną pętlę. Po drugiej nieudanej próbie początkowej powinna się zatrzymać, ale nie działa.
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;
}
}
});
Więc ten kod:
- zaczyna się, gdy pierwszy wniosek nie
- Odświeża tokena
- ponawia prośbę, ale nie znowu (< - Chcę tylko, aby go zatrzymać tutaj)
- Odświeża token
- Ponawia żądanie, ale ponownie się nie powiedzie
- Odświeża tokena
- ponawia prośbę, ale nie znowu
- etc ...
To nie wygląda dobrze: 'return deferred.promise();'. Powinieneś właśnie zwrócić obiekt obietnicy 'return deferred.promise' i nie próbować go wykonywać. – user2943490