Site icon akquinet AG – Blog

AngularJS in WARs – The Case of the Session Timeout

Artikel in deutsch ⤴︎

AngularJS is a great framework to build modern web applications. Java EE offers a rich and powerful environment to build reliable, scalable, and secure server applications. The combination of both worlds is straight forward: The web archive (WAR) contains all the HTML pages and the JavaScript code. The access to the server is done using JAX-RS.

Also the access control can be implemented using the standard Java EE tools. Using form-based authentication, a user first has to enter login and password before he can access the web pages. In addition to the web pages the servlet used by the AngularJS application can be secured in the same way.

That should solve all problems, am I right? Almost. What is not covered by default is the handling of session timeouts. When a session times out the user is redirected to the login page to establish a new session. This is fine for a human user. An AngularJS application can get quite confused. It access the server in the background, expects a JSON response, and receives instead an HTML page. Here, we show a solution for this problem.

This solution is described in detail in our book. If you like to read (and buy) it, here is the link:
https://itunes.apple.com/de/book/rich-web-apps-mit-angularjs/id847457516

The example code of our solution is on GitHub:
https://github.com/akquinet/dailyplanner-angularjs

The idea is to check at every server request if the session is still valid. If it is not valid anymore, the browser is redirected to the login page. Because it is quite laborious to implement this for every server request again, we register an interceptor, named httpInterceptor, at the $httpProvider. This is done in the configuration phase of the application:

.config([
    "$httpProvider",
    function ($httpProvider) {
        $httpProvider
            .interceptors.push("httpInterceptor");
    }
]);

The next task is to recognize that a session got invalid. In this case the server is sending the login page as response. To distinguish the login page from other HTML pages, we added a meta information into the HTML-head of the page:

  <meta name="unauthorized" content="true">

Our interceptor now checks for every response if it is an HTML-page. If this is true, it looks for our added meta information. If it is found, the browser is redirected to the login page and the request itself is rejected, to allow the application to react on the error. This is the code:

.factory("httpInterceptor", ["$q", "$window", "$log",
  function ($q, $window, $log) {
    return {
     "response": function (response) {
        var responseHeaders;
        responseHeaders = response.headers();
        if (   responseHeaders["content-type"]
                 .indexOf("text/html") !== -1
               && response.data
               && response.data
                   .indexOf('<meta name="unauthorized" content="true">') 
                      !== -1) {
          $window.location.reload();
          return $q.reject(response);
        }
        return response;
      }
    };
 }
])

This solution works reliable. But it has two shortcomings:

Of course, if you know of a better solution, we would appreciate to hear about it.

🙂

Exit mobile version