web系统中登录超时返回登录页的逻辑必不可少,实现起来也不算复杂。但仍然需要区分ajax请求
和刷新页面请求
的不同处理,其中也需要考虑到iframe
嵌套页面中的ajax请求返回顶端登录页的情况。此处整理一个基于springboot和shiro框架的登录会话超时跳转登录页的实现。
一、拦截器
说明:
1、编写一个自定义拦截器实现Filter
,重写doFilter方法
2、使用@WebFilter
注解配置需要拦截的url
3、因为项目使用了shiro认证框架,所以此处的判断登录超时直接使用SecurityUtils.getSubject().isAuthenticated()
进行判断
4、根据请求头判断是否是ajax请求:
4.1、ajax请求需在返回头中设置自定义属性,然后再到前端做相应的跳转处理
4.2、非ajax请求比较简单,直接根据需要重定向到登录页的url即可
@WebFilter(urlPatterns = {"/base/*","/user/*"}, filterName = "authFilter")
public class AuthFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (!SecurityUtils.getSubject().isAuthenticated()) {// 会话超时
String requestHeader = request.getHeader("X-Requested-With");
if (StringUtils.isNotEmpty(requestHeader) && StringUtils.equals(requestHeader, "XMLHttpRequest")){// ajax请求
response.setHeader("session-status", "timeout");// 自定义属性和属性值返回
} else {// 刷新页面请求
response.sendRedirect("/");// 重定向到首页
}
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() {}
}
二、拦截到ajax请求后的处理
说明:新建一个公共js文件,放入如下代码,在需要“超时跳转登录页”的html页面引入该js。
$(function() {
// 其他的所有ajax在请求成功后都会指定到此方法
$.ajaxSetup({
complete: function (XMLHttpRequest, textStatus) {
// 通过XMLHttpRequest取得响应头中自定义的属性:session-status
let sessionStatus = XMLHttpRequest.getResponseHeader("session-status");
if (sessionStatus == "timeout") {// 超时跳转到登录页
window.location.href = "login";
}
}
});
})
三、处理iframe框的情况
说明:如果ajax请求不在一级页面,而在嵌套页面中,则需要在登录页的html中添加如下代码。不然只会在嵌套页面出现你的登录页。
<script language="javascript">
if (window.parent != window) {
top.location.href = window.location.href;
}
</script>