easyui shiro session times out and jumps to the login page

 Problem description: In the java web project, shiro is used as the security framework, and the front end uses easyui; when the session expires, shiro is configured to automatically jump to the login page url. When the session expires, using easyui to access an operation will not jump to the login page. The easyui operation code is as follows:

 

$("#formxx").form("submit", {
		url: 'addEntityurl',
		type : 'json',
		onSubmit : function(param) {
			var isValid = $(this).form("validate");
			if (!isValid) {
				$.messager.progress("close");
			}
			return isValid;
		},
		success : function(data) {
			var data = eval ('(' + data + ')');
			if (data.code > 0) {
				$.messager.alert("Prompt", "Save successfully");
			}
		}
	});
 The shiro code is as follows:

 

 

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="loginUrl" value="/login" />
		<!-- Login success page, jump to this page after successful login -->
        <property name="successUrl" value="/index"/>
</bean>
 

 

Specific cause:

      1. The process of the loginUrl configured by shiro to jump to the login page url when the session expires is for the case of ordinary data access, and additional processing is required in the asynchronous data access mode.

       2. Easyui's onSumbit form submission method is not an asynchronous ajax method, but regenerates an iframe and submits it with submit, which means that it is an ajax shelf. In fact, there is no asynchronous method parameter in the Request Header at all. Identification: X-Requested-With: XMLHttpRequest, as shown in the figure:

 

solution:

       1. The first step is to add a Filter to the project for the access situation of asynchronous ajax to determine whether the current access url is the ajax request url in the case of expiration ( identified by the asynchronous method parameter in the Request Header: X-Requested- With: XMLHttpRequest ), if it is an ajax request, then add a parameter to the Response Header: sessionstatus:timeout; the second step, write a global js file, set the global default configuration of AJAX through $.ajaxSetup, that is, get the Response Header parameter: sessionstatus, if sessionstatus== timeout, jump to the login page.

       2. Instead of using easyui's onSumbit form submission method, you can use jquery.ajax method.

 

The complete code of the solution is as follows:

    First, the code of the custom filter:

@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletRequest httpRequest = (HttpServletRequest)request;
		HttpServletResponse httpResponse = (HttpServletResponse)response;
		String requestUrl = httpRequest.getRequestURI().replace(httpRequest.getContextPath(), "");
		
		//Do not filter the image verification code path and SMS path
		if(!requestUrl.contains("/createImg") && !requestUrl.contains("/getPhoneMsg") && !SecurityUtils.getSubject().isAuthenticated()){
			if(null != httpRequest.getHeader("X-Requested-With") && httpRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
				//Set a sessionstatus status in the ajax response header for judgment in the ajax global js (common.js)
				httpResponse.setHeader("sessionstatus", "timeout");
				httpResponse.getWriter().print("timeout");//
				return;
			}
		}
		
		chain.doFilter(request, response);
	}

 

   Second, the global js code:

$.ajaxSetup({
	error : function(XMLHttpRequest, textStatus, errorThrown){
		if(XMLHttpRequest.status == 403){
			alert('You do not have permission to access this resource');
			return false;
		}
	},
	complete : function(XMLHttpRequest, textStatus){
		var sessionStatus = XMLHttpRequest.getResponseHeader("sessionstatus");
		console.log("sessionStatus= "+sessionStatus);
		if(sessionStatus == 'timeout'){
			var top = getTopWindow();
			top.location.href = '<c:url value="/" />';
		}
	}

});

function getTopWindow(){
	var p = window;
	while (p != p.parent){
		p = p.parent;
	}
	return p;
}

 

    3. Asynchronous form submission code:

function saveEntity(index) {
        //Do not use easyui's onsubmit method, the new ajax method is: verify the form first, then submit
	if(validate("formxx")){
		$.ajax({
			type : 'POST',
			url: 'addentityurl',
			data:$('#formxx').serialize(),
			success : function(data) {
				if (data.code > 0) {
					$.messager.alert("Prompt", "Save successfully");
				}
			}
		});
	}
}

function validate(id){
    var validate = $("#"+id).form('validate');
    if(!validate){
    	$.messager.alert("Confirm", 'Please fill in the form correctly!',"",function(){
    		$("#"+id).find(".validatebox-invalid:first").focus();
        });
        return false;
    }
    return true;
}

The above method cannot be implemented if there are attachments in the form that need to be uploaded, so it is recommended to use the jquery.easyui+jquery.form plugin, the code is as follows:

 

function saveEntity(index) {
	//This is the submit method of the jquery.form plugin
	$("#formxx").ajaxSubmit({
		type: "POST",
		url:"addurl",
		dataType: "json",
		beforeSubmit: function(a,form,options){
			//This is the form validation of easyui
			var isValid = $("#formxx").form("validate");
			if (!isValid) {
				$.messager.progress("close");
			}
			
			return isValid;
		},
	    success: function(data){
			if (data.code > 0) {
				$.messager.alert("Prompt", "Save successfully");
			} else {
				$.messager.alert("Prompt", "Save failed");
			}
		}
	});
	
}

 

 

 

  In short: I feel trapped by easyui's form submission method, saying that it is asynchronous, but not at all; for example, easyui's official website says that there is another ajax form submission method:

$('#ff').form({
    url:...,
    onSubmit: function(){
		// do some check
		// return false to prevent submit;
    },
    success:function(data){
		alert(data)
    }
});
// submit the form
$('#ff').submit();

 But I checked the Request Header through chrome, and there is no X-Requested-With: XMLHttpRequest logo in it at all, so I am a little puzzled here.

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327042872&siteId=291194637