Search code examples
angularjsnode.jsauthenticationjwtexpress-jwt

My authentication token interceptor does not intercept request/response of fresh route


I am trying to implement jwt authentication for my nodejs, express and angularjs app. So far I have generated the token, and stored it in my localStorage. According to this tutorial, I have implemented the authInterceptor in angular factory as follows:

app.factory('authInterceptor', function ($rootScope, $q, $window) {
  return {
    request: function (config) {
      config.headers = config.headers || {};
      if ($window.localStorage.myToken) {
        config.headers.Authorization = 'Bearer ' + $window.localStorage.myToken;

      }
      return config;
    },
    response: function (response) {
      if (response.status === "401") {
        $window.location.replace('/dash');
      }
      return response || $q.when(response);
    }
  };
});

I have pushed the interceptor in config file as follows:

$httpProvider.interceptors.push('authInterceptor');

So far I have sent the credentials to server, generated the token and stored it in localStorage.

So as long as I have not deleted the token from localStorage, and the token has not expired, I think it is supposed to persist. If I make requests from within the loaded page using the background ajax call of angularjs, the authentication header is set as it is supposed to.

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYSIsInR5cGUiOiJzYWxlcyIsImlhdCI6MTQyMjI2MDExMCwiZXhwIjoxNDIyMjc4MTEwfQ.Iv6W-Tc8Qm4FGclzmgbtjvWFz_tyDwEvrFmMmucONpY

However neither my request nor my response is intercepted when I navigate to a new route. For eg, I have my '/sales' route. But when I navigate to sales route from address bar, neither the request authentication header is set by the interceptor, thus returning authorization error 401 from server, which is not intercepted either; hence not redirecting to /dash.

Here is link of the error, and the headers of GET request to unauthorized route '/sales': request and response header at 401 error


Solution

  • What I have understood so far is, normally before javascript frontend frameworks how the http request were served was:

    • We type a url in address bar.
    • The browser sends the request.
    • The server gets the request.
    • serves the necessary html, js and css files.
    • browser renders it.

    But as the recent shift to various javascript frontend frameworks and use of RESTful api.s has begun, the request needs to have authorization header. Thus in many of the single page web apps with javascript frameworks like angularjs,

    • the initial request for '/' router is sent
    • the server serves the web application to the browser
    • all the further routing in the web application is done within the front end application, hence the "#" after the url.
    • Requests are made by the application to fetch, update, delete or post from the application through angular js.

    So when a request is made from angular application, it is intercepted from angular application and intercepted by your interceptor. However when a url is entered from the address bar, the browser sends request directly to server, because at that point of the request, the browser has not loaded the angular web application.

    What I did was you set html5mode to false and put a # before your route.

    like localhost/#/some-route and do the routing from your route provider. When there is # before your route, the request for / goes to server, the application loads, and then the request is sent through the application. Now from this some-route, make some controller make request to the desired server endpoint, which will be intercepted by interceptor.