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...