天天看點

Shiro中Session過期頁面跳轉回登入頁面處理問題

Session逾時的兩種情況:

shiro在管理session後,在session逾時會進行跳轉,這裡有兩種情況需要考慮,一種是ajax方式的請求逾時,一種頁面跳轉請求的逾時;

解決問題的思路:通過定義過濾器來檢查是否Session過期問題,目前是否session逾時,逾時判定是否是ajax請求,如果是ajax請求,則在response頭部設定session-status值,傳回到前端讀取到相應值後進行處理;

背景代碼

package xxxxxx.sys_common.core.shiro.filter;

import java.util.HashMap;

import java.util.Map;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import org.apache.shiro.web.filter.AccessControlFilter;

import xxxxxx.model.entity.SysUser;

import xxxxxx.core.shiro.token.manager.TokenManager;

import xxxxxx.utils.LoggerUtils;

public class LoginFilter extends AccessControlFilter {

    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {

        SysUser token = TokenManager.getToken();

        //Session未失效時驗證通過

        if(null != token || isLoginRequest(request, response)){

            return Boolean.TRUE;

        }

       //如果是ajax請求響應頭會有,x-requested-with 

       if(ShiroFilterUtils.isAjax(request)){

            LoggerUtils.debug(getClass(), "目前使用者沒有登入,并且是Ajax請求!");

            ShiroFilterUtils.out(response, resultMap);

            //通過傳回TRUE,通過前台的統一AJAX接受頭部設定的sessionstatus參數,判斷是否跳轉到登入頁面

            return Boolean.TRUE;

        }//FALSE  Session失效,切實非AJAX請求,驗證是否,調用onAccessDenied跳轉到登入頁面

        return Boolean.FALSE;

    }

    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

        //儲存Request和Response 到登入後的連結

        saveRequestAndRedirectToLogin(request, response);

        return false;

    }

}

package xxxxxx.core.shiro.filter;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Map;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import xxxxxx.LoggerUtils;

import net.sf.json.JSONObject;

public class ShiroFilterUtils {

    final static Class<? extends ShiroFilterUtils> CLAZZ = ShiroFilterUtils.class;

    //登入頁面

    static final String LOGIN_URL="/u/login";

    //沒有授權提醒

    static final String UNAUTHORIZED = "/open/unauthorized";

    public static boolean isAjax(ServletRequest request){

        return "XMLHttpRequest".equalsIgnoreCase(((HttpServletRequest)request).getHeader("X-Requested-With"));

    }

    public static void out(ServletResponse servletResponse){

        HttpServletResponse response = (HttpServletResponse) servletResponse;        

        response.setCharacterEncoding("UTF-8");

        //在響應頭設定session狀态

        response.setHeader("session-status", "timeout");

    }

}

shiro.xml配置檔案

<bean id="login" class="com.htdadao.pms.sys_common.core.shiro.filter.LoginFilter"/>

 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

        <property name="filters">

            <util:map>

                <entry key="login" value-ref="login"></entry>

            </util:map>

        </property>

    </bean>

前台代碼

<script>

      //全局的ajax通路,處理ajax清求時session逾時

      $.ajaxSetup({

         contentType:"application/x-www-form-urlencoded;charset=utf-8",

         complete:function(XMLHttpRequest,textStatus){

             //通過XMLHttpRequest取得響應頭,sessionstatus,

             var sessionstatus=XMLHttpRequest.getResponseHeader("session-status");

             if(sessionstatus=="timeout"){

                 //如果逾時就處理 ,指定要跳轉的頁面(比如登陸頁)

                 window.location.replace("<%=realPath%>"+"/u/login");

             }

          }

       });

 </script>

參考

Shiro中session逾時頁面跳轉的處理  http://blog.csdn.net/jrn1012/article/details/70396502

Ajax狀态值及狀态碼  http://www.cnblogs.com/luoguixin/p/6249566.html

 jQuery - 攔截所有Ajax請求(統一處理逾時、傳回結果、錯誤狀态碼 )(備注:分别可以通過設定header,傳回Json,或者設定HTTP的status指的方式傳回前台通知逾時)http://www.hangge.com/blog/cache/detail_1412.html