JSFiddle - React, Tailwind, and code Playground
by Andrea Aloi
HTML
<script src="https://code.angularjs.org/1.3.11/angular.min.js"></script>
<script src="https://code.angularjs.org/1.3.11/angular-mocks.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<button type="button" ng-click="issueRequest()">Issue an API request</button>
<hr/>
<button type="button" ng-click="simulateSessionExpiration()">Simulate session expiration</button>
</body>
JavaScript
console.clear();
var user = {token: "valid"};
var apiInterceptor = function($q, $injector) {
return {
request: function(request) {
if(request.url.charAt(0) === "/") {
console.info("apiInterceptor - request", request.url);
if(user && user.token) {
request.headers["Authorization"] = "Bearer " + user.token;
}
request.maxAttempts = 2;
}
return request || $q.when(request);
},
responseError: function(response) {
if(response.status === 401) {
console.info("apiInterceptor - responseError 401", response.config.url);
//Unauthorized
if(user && user.token) {
//If user was previously logged in, renew access_token silently
//and re-issue request;
response.config.maxAttempts--;
if(response.config.maxAttempts) {
return $injector.get("login")().then(function() {
//Login successful: retry request
var $http = $injector.get("$http");
return $http(response.config);
}, function(err) {
//Login failed: abort and redirect to login page
return $q.reject(err);
});
}
}
//Should never happen: no user or user exists but has no access_token,
//redirect to login page
}
return $q.reject(response);
}
};
};
angular.module("myApp", ["ngMockE2E"])
.config(["$httpProvider", function($httpProvider) {
$httpProvider.interceptors.push("apiInterceptor");
}])
.factory("apiInterceptor", ["$q", "$injector", apiInterceptor])
.service("login", ["$http", function($http) {
return function() {
return...