我使用拦截器检查用户是否登录了每个控制器调用,如下所示:
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(..)
。
如何知道这是ajax还是正常请求?
如果我收到ajax错误怎么办呢?
$.ajax({
.....
success : function(data) { ...... },
error : function(){
alert("login error"); // or
document.location = '/path/login' // or something else
}
});
还有另一种方法来处理它而不是使用拦截器吗?
答案 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方法中阅读,该方法是在success
或error
之后的回调,例如。
$.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)
你可以简单地说:
此外,preHandle不必适用于每条路线,您也可以使用不同的路线,每条路线都有不同的授权,预处理,代码。