使用normal和ajax请求检查记录的用户

时间:2015-10-22 02:23:36

标签: spring-mvc

我使用拦截器检查用户是否登录了每个控制器调用,如下所示:

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;
}

它适用于正常请求但是对于ajax请求我无法生成response.sendRedirect(..)

  1. 如何知道这是ajax还是正常请求?

  2. 如果我收到ajax错误怎么办呢?

    $.ajax({ 
       .....
       success : function(data) { ...... },     
       error   : function(){ 
              alert("login error"); // or 
              document.location = '/path/login' // or something else
       }
    
    });
    
  3. 还有另一种方法来处理它而不是使用拦截器吗?

2 个答案:

答案 0 :(得分:2)

1。如何知道它是ajax还是正常请求?

您可以在拦截器内检查是否存在X-Requested-With标头。这个头总是被jQuery库添加到ajax请求中(我知道几乎所有主要的js库都添加它),目的是阻止Cross-Site request forgery。要确定请求是否为ajax,您可以编写preHandle方法,如

    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。我怎么能这样做,如果我得到ajax错误?

正如您已经注意到的,ajax请求无法识别服务器端重定向,因为服务器端重定向的意图是对客户端透明。在ajax请求的情况下,不要重定向而是将某些状态代码设置为响应,例如response.setStatus(respCode)或添加自定义标头,例如response.setHeader("Location", "/path/login"),并在jQuery的complete方法中阅读,该方法是在successerror之后的回调,例如。

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

3。有另一种方法来处理它而不是使用拦截器吗?

当然。结帐Spring Security。它是一个框架,并为学习曲线增加了一点,但它非常值得。它将添加远远超过自定义解决方案,例如您将在身份验证之上获得授权机制。当您的应用程序成熟时,您会注意到您现在所采用的实施方式,存在很多不易被利用的安全漏洞,例如: session fixation,春天安全可以轻松保护你。网上有很多例子,与任何自定义解决方案相比,你可以在SO上获得更好的支持。你可以对它进行单元测试,这是我个人非常看重的资产

答案 1 :(得分:1)

你可以简单地说:

  • 在用户正确登录前拒绝ajax请求
  • 一旦用户登录,在会话或某个地方设置安全令牌
  • 在ajax请求中传递该令牌,并使用该令牌在服务器端进行预处理
  • 在您的情况下,您将在运行代码
  • 之前检查令牌是否存在

此外,preHandle不必适用于每条路线,您也可以使用不同的路线,每条路线都有不同的授权,预处理,代码。