springboot shiro session过期跳转到登录页

背景:

       想实现一个 session过期,然后系统自动校验,然后跳转到登录页的功能,研究了好几天,终于研究出来了。

编写拦截器:

       需要编写一个拦截器 ClearSessionCacheFilter 来拦截用户的 ajax请求,若当前的 session处于超时状态,则给他设置 session-status 为 timeout,然后在 js文件里面做一个校验即可。

public class ClearSessionCacheFilter 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;
        String basePath = request.getContextPath();
        request.setAttribute("basePath", basePath);
        // 判断 session 里是否有用户信息
        if (!SecurityUtils.getSubject().isAuthenticated()) {
        	 // 如果是ajax请求响应头会有,x-requested-with
            if (request.getHeader("x-requested-with") != null
                    && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
        		// 在响应头设置session状态
                response.setHeader("session-status", "timeout");
                return;
            }
        }
        filterChain.doFilter(request, servletResponse);
	}

	@Override
	public void destroy() {
		
	}
}

配置 ShiroConfig :

       需要将上面新增的 ClearSessionCacheFilter 配置到 ShiroConfig 中,代码如下所示:

    /**
	 * 校验当前缓存是否失效的拦截器
	 * 
	 * */
	@Bean
	public ClearSessionCacheFilter clearSessionCacheFilter() {
		ClearSessionCacheFilter clearSessionCacheFilter = new ClearSessionCacheFilter();
		return clearSessionCacheFilter;
	}

    // Filter工厂,设置对应的过滤条件和跳转条件
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
		// Shiro的核心安全接口,这个属性是必须的
		shiroFilter.setSecurityManager(securityManager);	
	
		//不输入地址的话会自动寻找项目web项目的根目录下的/page/login.jsp页面。
		shiroFilter.setLoginUrl("/login");
		//登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,则在登录自动跳转到那个需要登录的页面。不跳转到此。
		//shiroFilter.setSuccessUrl("/");
		
		// 自定义拦截器处理session过期的操作
	    LinkedHashMap<String, Filter> filtersMap = new LinkedHashMap<>();	  
	    filtersMap.put("clearSession", SystemFilter());
	    shiroFilter.setFilters(filtersMap);
	    
		//没有权限默认跳转的页面
		//shiroFilter.setUnauthorizedUrl("");
		
		//filterChainDefinitions的配置顺序为自上而下,以最上面的为准
		//shiroFilter.setFilterChainDefinitions("");
        // Shiro验证URL时,URL匹配成功便不再继续匹配查找(所以要注意配置文件中的URL顺序,尤其在使用通配符时),配置不会被拦截的链接 顺序判断
		Map<String, String> map = new LinkedHashMap<>();
		
		// 不能对login方法进行拦截,若进行拦截的话,这辈子都登录不上去了,这个login是LoginController里面登录校验的方法
		map.put("/login", "anon"); 
		map.put("/static/**", "anon");
		//map.put("/", "anon");
		//对所有用户认证
		map.put("/**", "clearSession,authc");
		
		shiroFilter.setFilterChainDefinitionMap(map);
		return shiroFilter;
	}

前端代码:

      在我们平常的项目中,一般都会引入一些公共的 js文件,在里面添加一些常用的工具方法或者常量,这时我们需要在 js 文件中添加一个 ajax的父级方法 $.ajaxSetup ,用于拦截ajax返回后的数据,用于校验当前的 session是否处于过期状态,若处于过期状态则跳转到首页,代码如下所示:

function addRoleIds(){

	$.ajax({
		url :"addRoleIds",
		data : {"userName" : "lisi"} ,
		async:false,
		type : "get",
		success : function(data) {
			alert(data);
		}
	})
}

function delRoleIds(){

	$.ajax({
		url :"delRoleIds",
		data : {"userName" : "zhangsan"} ,
		async:false,
		type : "get",
		success : function(data) {
			alert(data);
		},

	})
}
$.ajaxSetup({
	complete:function(XMLHttpRequest,textStatus){
		var sessionstatus=XMLHttpRequest.getResponseHeader("session-status");
		if(sessionstatus == "timeout"){
			alert("会话超时,请重新登录!")
			//如果超时就处理 ,指定要跳转的页面
			window.location.href= "/login";
		}		
	}
});

 


版权声明:本文为xhf852963原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。