Check the connected user with a normal query and ajax

advertisements

I use interceptor to check if a user is logged in every controller call like this :

public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) {

    if(request.getSession().getAttribute("user") == null) {
        response.sendRedirect("redirect:/login?next="+
             URLEncoder.encode(
                   request.getRequestURL().toString() + "" +
                   (request.getQueryString() != null ? "?" + request.getQueryString() : "")
            ,"utf-8");

        return false;
    }   

    return true;
}

It work fine for normal request but for ajax request i can't make a response.sendRedirect(..).

  1. How to know if it's a ajax or normal request ?

  2. How can i do it like if i got a ajax error ?

    $.ajax({
       .....
       success : function(data) { ...... },
       error   : function(){
              alert("login error"); // or
              document.location = '/path/login' // or something else
       }
    
    });
    
    
  3. There a other way to handle it rather than using interceptor ?


1. How to know if it's a ajax or normal request ?

You can check inside your interceptor for the existence of the X-Requested-With header. This header is always added to the ajax request by the jQuery library (to my knowing almost all major js libraries add it as well) with the purpose of preventing the Cross-Site request forgery. To figure out if the request is ajax, you can write your preHandle method like

    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) {
        String requestedWith = request.getHeader("X-Requested-With");
        Boolean isAjax = requestedWith != null ? "XMLHttpRequest".equals(requestedWith) : false;
...
}

2. How can i do it like if i got a ajax error ?

As you've already noticed, ajax request don't recognize server side redirects, as the intention of the server side redirects is to be transparent to the client. In the case of an ajax request, don't do redirect rather set some status code to the response e.g. response.setStatus(respCode) or add a custom header e.g. response.setHeader("Location", "/path/login"), and read it through in the jQuery's complete method which is a callback that follows after either success or error, e.g.

$.ajax({
    //...
    complete: function(xhr, textStatus) {
        console.log(xhr.status);
        console.log(xhr.getResponseHeader('Location'));
        // do something e.g. redirect
    }
});

3. There a other way to handle it rather than using interceptor ?

Definitely. Checkout Spring Security. Its a framework, and adds a bit to the learning curve, but its well worth it. It will add much more than a custom solution, e.g. you'll get authorization mechanism on top of the authentication. When your application matures, you'll notice that the straigthforward implementation that you're on to now, has quite a few security flaws that are not hard to exploit e.g. session fixation, where spring security can easily protect you. There's plenty of examples online, and you'll get better support here on the SO in comparison to any custom solution. You can unit test it, an asset I personally value very much