springboot整合shiro实现session过期后自动跳转登录页面:

登录系统后在session失效后再进行点击系统页面时自动跳转到登录页面

1.后端代码实现:

springboot整合shiro实现登录验证授权基础代码上进行修改。

添加验证session失效重新跳转登录页面过滤器:

public class LoginFilter  extends FormAuthenticationFilter {
    private static final String[] filter = { "/css",  ,"/img", "/icons","/html", "/js"};

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest hsRequest = (HttpServletRequest) request;
        HttpServletResponse hsResponse = (HttpServletResponse) response;
        String url = hsRequest.getRequestURI();

        // 不需要过滤的请求地址以及文件
        for (String str : filter) {
            if (url.contains(str) || url.equalsIgnoreCase("/")){
                return true;
            }
        }
        //这里是获取用户登录信息
        Subject subject = getSubject(request, response);
        // 如果没有获取到用户信息,将退出到登陆界面
        if (null == subject.getPrincipal()) {
            boolean isAjaxRequest = false;
            if(!StringUtils.isBlank(hsRequest.getHeader("x-requested-with")) && hsRequest.getHeader("x-requested-with").equals("XMLHttpRequest")){
                isAjaxRequest = true;
            }
            // 如果是Ajax返回指定数据
            if (isAjaxRequest) {
                //可以通过code403判断是否重定向,也可以自定义一个属性指定是session超时的重定向
                hsResponse.setHeader("sessionstatus", "TIMEOUT");	//返回特定数据(头部信息)
                hsResponse.setHeader("content_path", "/account/login");	//返回特定数据(首页登陆地址)
                hsResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);	//403禁止
                return false;
            } else {	// 不是Ajax进行重定向处理
                hsResponse.sendRedirect("/account/login");	//重定向到登陆界面
                return false;
            }
        }
        return true;
    }
}

在shiroConfig类中添加过滤器验证:

 //Filter工厂,设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new HashMap<>();
        //登出
        map.put("/logout", "logout");
        //登录
        map.put("/loginSubmit", "anon");
        //静态文件包
        map.put("/res/**", "anon");
       
        // 添加自己的过滤器并且取名为loginFilter
        Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
        filterMap.put("loginFilter", new LoginFilter());
        shiroFilterFactoryBean.setFilters(filterMap);
        //过滤链定义,从上向下顺序执行,一般将/**放在最为下边
        filterChainDefinitionMap.put("/**", "loginFilter");

        //登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //错误页面,认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    //配置session超时时间
    @Bean
    public DefaultWebSessionManager getDefaultWebSessionManager() {
        DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
        // 会话过期时间,单位:毫秒(在无操作时开始计时),设置30分钟
        defaultWebSessionManager.setGlobalSessionTimeout(30* 1000 * 60);
        defaultWebSessionManager.setSessionValidationSchedulerEnabled(true);
        defaultWebSessionManager.setSessionIdCookieEnabled(true);
        return defaultWebSessionManager;
    }

这样再session失效后,再在系统点击任一个页面操作,都会经过过滤器验证,进行跳转登录页面。

2.前端代码实现:

创建一个common.js,覆盖ajax请求。在每个html页面都引入这个js。这样一来在session失效后再进行点击ajax提交时就不会再进行操作,会自动跳到登录页面。

//设置session超时跳转页面start
if(typeof jQuery != 'undefined') {
	//重写ajax
	$.ajaxSetup( {
		//设置ajax请求结束后的执行动作
		complete :
			function(XMLHttpRequest, textStatus) {
				// 通过XMLHttpRequest取得响应头,sessionstatus
				var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus");
				if (sessionstatus == "TIMEOUT") {
					var win = window;
					while (win != win.top) {
						win = win.top;
					}
					win.location.href = XMLHttpRequest.getResponseHeader("content_path");
				}
			}
	});
}

// 如果使用了layui框架,也必须要重写layui的ajax
if(typeof layui != 'undefined') {
	$.ajaxSetup({
		complete: function(XMLHttpRequest, textStatus) {
			// 通过XMLHttpRequest取得响应头,sessionstatus
			var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus");
			if (sessionstatus == "TIMEOUT") {
				var win = window;
				while (win != win.top) {
					win = win.top;
				}
				win.location.href = XMLHttpRequest.getResponseHeader("content_path");
			} else {
				if (textStatus == 'timeout') {
					$.modal.alertWarning("服务器超时,请稍后再试!");
					$.modal.enable();
					$.modal.closeLoading();
				} else if (textStatus == "parsererror" || textStatus == "error") {
					$.modal.alertWarning("服务器错误,请联系管理员!");
					$.modal.enable();
					$.modal.closeLoading();
				}
			}
		}
	});
}
//设置session超时跳转页面end

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐