Detailed explanation. net mvc session failure problem

  • 2021-08-16 23:33:22
  • OfStack

Recently in the research related. net mvc project session failure problem, the following site to share the research process for everyone, you can refer to the next.

Recently, the failure problem of session based on. net mvc project was solved. Let's talk about this.

1. Problem analysis

In net mvc, Session failure needs to be considered in several situations:

Action based on authority authentication, using non-Ajax requests;

Action based on authority authentication, using JQueryt Ajax request;

Action based on authority authentication, Ajax request encapsulated with. net mvc;

Action without authority authentication, using non-Aajx request;

Action without authority authentication, using native JQuery Ajax request;

Action without authority authentication, Ajax request encapsulated with. net mvc;

Action based on authority authentication and AuthorizeAttribute can be intercepted after session fails, and processed in HandleUnauthorizedRequest method; Action without authority authentication needs to be judged and processed in the custom filter according to the difference between the newly created Session and the requested Session.

2. Non-Ajax requests based on authority authentication

Authorize filter takes precedence over other functional filters, so AuthorizeAttribue is inherited here and session requests are processed in HandleUnauthorizedRequest.


public class AuthorizeOfHandleUnAuthorizeAttribute:AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//session Invalidation redirection to login page 
filterContext.Result =
new RedirectToRouteResult(
new RouteValueDictionary(new { Controller = "Login", Action = "Login" }));
}
}

3. Ajax request based on authority authentication

Action requested by Ajax has two return results in the system: JsonResult and PartialViewResult.

In theory, JsonResult can be judged by the client by adding session overdue attribute to the returned result. But adding judgment logic to all ajax requests is cumbersome considering the project is complete.

Server-side code handles ajax requests:


protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//ajax Request session Overdue processing 
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.AppendHeader("sessionstatus","timeout");
filterContext.HttpContext.Response.End();
return;
}
filterContext.Result =
new RedirectToRouteResult(
new RouteValueDictionary(new { Controller = "Login", Action = "Login" }));
}

Client-side code (this processing is not applicable for Action that returns PartialViewResult):


onSuccess: function (xhr, status) {
// Gets the response header, sessionstatus , 
var sessionstatus = xhr.getResponseHeader("sessionstatus");
if (sessionstatus == "timeout") {
window.location = "/Login/Login";
}
}

The existence of ES 101 EN directly denies the above assumption. Most Ajax requests in the project are encapsulated based on. net mvc, directly updating the specified div.

In order not to make a lot of changes, and to process two ajax requests that return results, we found another method

jQuery.ajaxSetup()

This function is used to change the default setting options for AJAX requests in jQuery. All subsequent AJAX requests will use the changed default settings if the corresponding option parameters are not set.

Therefore, our client code can be treated as follows:


// Analyse ajax Request session Timeout problem 
$.ajaxSetup({
complete: function(xmlHttpRequest, textStatus) {
var sessionStatus = xmlHttpRequest.getResponseHeader("sessionstatus");
if (sessionStatus === "timeout") {
window.location = "/Login/Login";
}
}
});

I thought everything would be all right here. As a result, I accidentally found another problem. The request call of ajax encapsulated by jquery. unobtrusive-ajax based on. net mvc did not achieve the effect of interception processing. After repeated debugging, I finally noticed the above paragraph

jQuery. ajaxSetup () This function is used to change the default setting options for AJAX requests in jQuery. All subsequent AJAX requests will use the changed default settings if the corresponding option parameters are not set.

What is said here is quite clear. It must be the ghost when jquery. unobtrusive-ajax is encapsulated. Open the source code 1 and see it as it is:


$.extend(options, {
type: element.getAttribute("data-ajax-method") || undefined,
url: element.getAttribute("data-ajax-url") || undefined,
cache: !!element.getAttribute("data-ajax-cache"),
beforeSend: function (xhr) {
var result;
asyncOnBeforeSend(xhr, method);
result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(element, arguments);
if (result !== false) {
loading.show(duration);
}
return result;
},
complete: function (xhr,status) {
loading.hide(duration);
getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(element, arguments);
},
success: function (data, status, xhr) {
asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(element, arguments);
},
error: function () {
getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]).apply(element, arguments);
}
});

We saw that jquery. unobtrusive-ajax registered the compelete event requested by ajax, so the default handler we wrote was overwritten. Really did not think what good method, had to change the source code of jquery. unobtrusive-ajax:


complete: function (xhr,status) {
loading.hide(duration);
// Analyse ajax Request session Timeout problem 
var sessionStatus = xhr.getResponseHeader("sessionstatus");
if (sessionStatus === "timeout") {
window.location = "/Login/Login";
}
getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(element, arguments);
},

At this point, the failure problem of authentication-based ajax request session is basically solved, and there are two flaws:

Modified the source code of jquery. unobtrusive-ajax, and always felt uncomfortable;

Any ajax request that registers an compelete event needs to handle the session issue itself.

4. Action for unauthorized tasks

Session failure problem of Action without authority authentication, the processing code is as follows:


if (filterContext.HttpContext.Session != null)
{
if (filterContext.HttpContext.Session.IsNewSession)
{
var sessionCookie = filterContext.HttpContext.Request.Headers["Cookie"];
if (sessionCookie != null&&sessionCookie.IndexOf("ASP_NET_SessionId",StringComparison.OrdinalIgnoreCase)>=0)
{
filterContext.Result =
new RedirectToRouteResult(
new RouteValueDictionary(new { Controller = "Login", Action = "Login" }));
}
}
}

No authority authentication of Action Ajax can imitate the above authority authentication processing method, here is no longer sticky code. Personally, most Action requests without authority authentication can not consider the failure of session, because most of these Action do not obtain information from session, but only query public information.

5. Remaining issues

At this point, the problem has been basically solved, but an inexplicable problem has been encountered in the process. Let's write it down for the time being:

I originally simulated the failure of session by setting the session overdue time very small in the configuration file, but found that the existing framework of the project always inexplicably changed the session overdue time to 60 minutes when the first business request after logging in, but did not find why. Later, it can only be simulated by opening two tab pages in the same browser, logging in to the system and launching one tab page.


Related articles: