解决Shiro|解决Shiro 处理ajax请求拦截登录超时的问题

目录

  • Shiro 处理ajax请求拦截登录超时
    • 配置全局ajax配置
  • Shiro session超时页面跳转的处理
    • 问题描述
    • ajax请求超时处理
      • 后端Filter代码
      • 前端通用ajax处理
    • 非ajax请求超时跳转

    Shiro 处理ajax请求拦截登录超时
    配置全局ajax配置
    $.ajaxSetup({complete:function(XMLHttpRequest,textStatus){if(textStatus=="parsererror"){$.messager.alert('提示信息', "登陆超时!请重新登陆!", 'info',function(){window.location.href = 'https://www.it610.com/article/login.jsp'; }); } else if(textStatus=="error"){$.messager.alert('提示信息', "请求超时!请稍后再试!", 'info'); }}});

    在js里面配置全局的ajax配置即可!

    Shiro session超时页面跳转的处理
    问题描述
    shiro在管理session后,在session超时会进行跳转,这里有两种情况需要考虑,一种是ajax方式的请求超时,一种页面跳转请求的超时。
    本文从这两个方面分别考虑并处理。

    ajax请求超时处理
    思路:通过Filter后判定,当前是否session超时,超时判定是否是ajax请求,如果是ajax请求,则在response头部设置session-status值,返回到前端读取到相应值后进行处理

    后端Filter代码
    package com.cnpc.framework.filter; import org.apache.shiro.SecurityUtils; import org.apache.shiro.session.Session; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * * filter过滤器,获取项目路径,设置ajax超时标识 * @author billJiang QQ:475572229 */public class SystemFilter implements Filter {public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException,ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; System.out.println(request.getRequestURL()); String basePath = request.getContextPath(); request.setAttribute("basePath", basePath); if (!SecurityUtils.getSubject().isAuthenticated()) {//判断session里是否有用户信息if (request.getHeader("x-requested-with") != null&& request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {//如果是ajax请求响应头会有,x-requested-withresponse.setHeader("session-status", "timeout"); //在响应头设置session状态return; }}filterChain.doFilter(request, servletResponse); }@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void init(FilterConfig arg0) throws ServletException {// TODO Auto-generated method stub}}


    前端通用ajax处理 注意session-status上下文部分
    function ajaxPost(url, params, callback) {var result = null; var headers={}; headers['CSRFToken']=$("#csrftoken").val(); $.ajax({type : 'post',async : false,url : url,data : params,dataType : 'json',headers:headers,success : function(data, status) {result = data; if(data&&data.code&&data.code=='101'){modals.error("操作失败,请刷新重试,具体错误:"+data.message); return false; }if (callback) { callback.call(this, data, status); }},error : function(err, err1, err2) {console.log("ajaxPost发生异常,请仔细检查请求url是否正确,如下面错误信息中出现success,则表示csrftoken更新,请忽略"); console.log(err.responseText); if(err && err.readyState && err.readyState == '4'){var sessionstatus=err.getResponseHeader("session-status"); if(sessionstatus=="timeout"){//如果超时就处理 ,指定要跳转的页面window.location.href=https://www.it610.com/article/basePath+"/" ; }else{//csrf异常var responseBody = err.responseText; if (responseBody) {responseBody = "{'retData':" + responseBody; var resJson = eval('(' + responseBody + ')'); $("#csrftoken").val(resJson.csrf.CSRFToken); this.success(resJson.retData, 200); }return; }}modals.error({text : JSON.stringify(err) + '
    err1:' + JSON.stringify(err1) + '
    err2:' + JSON.stringify(err2),large : true}); }}); return result; }


    非ajax请求超时跳转
    在本试验中,使用jquery.load方式进行了页面加载,并重载jquery.fn.load改写了该方法,通过beforeSend去除了ajax标识,由于超时返回的登录页面可能嵌入当前页面,所以需要判断当前获得的页面是否是登录页面,如果是登陆页面,则再经过一次跳转到登陆页(或者首页)。
    重载的jquery.fn.load方法如下,注意beforeSend和responseText.startWith部分内容。
    var _old_load = jQuery.fn.load; jQuery.fn.load = function( url, params, callback ) {//update for HANZO, 2016/12/22if (typeof url !== "string" && _old_load) {return _old_load.apply( this, arguments ); }var selector, type, response,self = this,off = url.indexOf( " " ); if ( off > -1 ) {selector = jQuery.trim( url.slice( off ) ); url = url.slice( 0, off ); }if ( jQuery.isFunction( params ) ) {callback = params; params = undefined; } else if ( params && typeof params === "object" ) {type = "POST"; }if ( self.length > 0 ) {jQuery.ajax( {url: url,beforeSend: function( xhr ) {xhr.setRequestHeader('X-Requested-With', {toString: function(){ return ''; }}); },type: type || "GET", dataType: "html",data: params} ).done( function( responseText ) {//console.log(responseText); response = arguments; //页面超时跳转到首页if(responseText.startWith("")){window.location.href=https://www.it610.com/article/basePath+"/"; }else{self.html(selector ?jQuery("").append(jQuery.parseHTML( responseText )).find(selector) :responseText); }} ).always( callback && function( jqXHR, status ) {self.each( function() {callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); } ); } ); }return this; };

    可通过设置session的timeout来测试结果。需要注意的是ajax请求要使用ajaxPost方法,该方法统一处理了超时跳转。
    【解决Shiro|解决Shiro 处理ajax请求拦截登录超时的问题】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

      推荐阅读