English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

详解.net mvc session失效问题

Recently, I have been studying the session expiration problem in .NET MVC projects, and I will share the research process with everyone below. You can refer to it.

Recently, I solved the session expiration problem in a .NET MVC project, and I would like to discuss it with everyone.

1. Problem analysis

In .NET MVC, there are several situations to consider when the session expires:

•Use non-Ajax requests for actions based on permission authentication;

•Use JQueryt AJAX requests for actions based on permission authentication;

•Use .NET MVC encapsulated AJAX requests for actions based on permission authentication;

•Use non-Ajax requests for actions without permission authentication;

•Use native JQuery AJAX requests for actions without permission authentication;

•Use .NET MVC encapsulated AJAX requests for actions without permission authentication;

For actions based on permission authentication, AuthorizeAttribute can intercept session expiration and handle it in the HandleUnauthorizedRequest method; for actions without permission authentication, they need to be judged and handled in a custom filter, based on the difference between the newly created session and the requested session.

7. Non-AJAX requests based on permission authentication

The Authorize filter is executed before other feature filters, so here we inherit AuthorizeAttribue and handle session requests in HandleUnauthorizedRequest.

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

3. AJAX requests based on permission authentication

There are two types of return results for the Action of AJAX requests in the system: JsonResult and PartialViewResult.

•Theoreticamente, JsonResult can be used to add a session timeout attribute to the returned result, and the client can make a judgment. However, considering that the project has been completed, adding judgment logic to all AJAX requests is somewhat cumbersome.

Gestione delle richieste AJAX sul lato server:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// Gestione della sessione scaduta per richieste AJAX
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" }));
}

Codice client (questo metodo di elaborazione non è applicabile alle azioni che restituiscono PartialViewResult):

onSuccess: function (xhr, status) {
// Ottieni l'intestazione di risposta, sessionstatus,
var sessionstatus = xhr.getResponseHeader("sessionstatus");
if (sessionstatus == "timeout") {
window.location = "/Login/Login";
}
}

• La presenza di PartialViewResult nega direttamente l'ipotesi sopra menzionata. La maggior parte delle richieste AJAX nel progetto sono basate su .net mvc e aggiornano direttamente il div specificato.

Per evitare cambiamenti estesi e trattare in modo uniforme entrambi i tipi di risultati delle richieste AJAX, ho trovato un altro metodo

jQuery.ajaxSetup()

Questa funzione serve a modificare le opzioni di default delle richieste AJAX in jQuery. Tutte le richieste AJAX eseguite successivamente, se non sono state impostate le opzioni corrispondenti, utilizzeranno le impostazioni di default modificate.

Di conseguenza, il nostro codice client può essere trattato in modo uniforme:

//解析ajax请求session超时问题
$.ajaxSetup({
complete: function(xmlHttpRequest, textStatus) {
var sessionStatus = xmlHttpRequest.getResponseHeader("sessionstatus");
if (sessionStatus === "timeout") {
window.location = "/Login/Login";
}
}
});

Pensavo che qui tutto fosse a posto, ma non ho potuto fare a meno di notare un altro problema: la chiamata AJAX encapsulata da jQuery.unobtrusive-ajax basata su .net mvc non ha raggiunto l'effetto di intercettazione del processo. Dopo molte prove senza successo, alla fine ho notato quella frase sopra.

jQuery.ajaxSetup() questa funzione serve a modificare le opzioni predefinite delle richieste AJAX in jQuery. Tutte le richieste AJAX eseguite successivamente, se non sono state impostate le opzioni corrispondenti, utilizzeranno le impostazioni predefinite modificate.

Ecco spiegato chiaramente, quindi deve essere un problema nel momento in cui jQuery.unobtrusive-ajax viene encapsulato, guardando il codice sorgente è proprio così:

$.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);
}
});

我们看到jquery.unobtrusive-ajax注册了ajax请求的compelete事件,因此我们写的默认处理程序就被覆盖啦。实在没想到什么好办法,只好改下jquery.unobtrusive-ajax的源码了:

complete: function (xhr,status) {
loading.hide(duration);
//解析ajax请求session超时问题
var sessionStatus = xhr.getResponseHeader("sessionstatus");
if (sessionStatus === "timeout") {
window.location = "/Login/Login";
}
getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(element, arguments);
},

至此,基于认证的ajax请求session失效问题基本解决,存在两个瑕疵:

•修改了jquery.unobtrusive-ajax的源码,总感觉心里别扭;

•任何注册了compelete事件的ajax请求,都需要自己处理session问题。

4.无权限任务的Action

无权限认证的Action的Session失效问题,处理代码如下:

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" }));
}
}
}

Le richieste Ajax di azioni senza autenticazione di permesso possono essere trattate seguendo il metodo di gestione con autenticazione di permesso sopra menzionato, non ripeterò il codice qui. Penso che le richieste di azioni senza autenticazione di permesso, la maggior parte delle quali non prelevano informazioni dalla sessione, ma eseguono solo query di informazioni pubbliche, non debbano considerare la situazione di invalidazione della sessione.

5. Problemi rimasti

Fino a questo punto, il problema è stato基本上 risolto, ma durante il processo, ho incontrato un problema misterioso, che annoto temporaneamente:

Originariamente, ho impostato il tempo di scadenza della sessione molto piccolo nel file di configurazione per simulare l'invalidazione della sessione, ma ho scoperto che la struttura del progetto esistente modificava misteriosamente il tempo di scadenza della sessione a 60 minuti durante la prima richiesta di business dopo il login. Non ho trovato la ragione. Successivamente, ho dovuto simulare l'uscita su una tab nella stessa scheda del browser, dopo aver effettuato il login.

Come ha spiegato l'editor a tutti di noi, il problema di invalidazione della sessione .net mvc, speriamo che sia utile a tutti. Se avete qualsiasi domanda, lasciate un commento e l'editor risponderà tempestivamente. In questo senso, anche un grande ringraziamento per il supporto al sito web del tutorial di urla!

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il copyright spetta ai rispettivi proprietari. Il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, il sito web non detiene i diritti di proprietà, non è stato editato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a notice#oldtoolbag.com (sostituisci # con @) per segnalare il problema, fornendo prove pertinenti. Una volta verificata la veridicità, il sito web eliminerà immediatamente i contenuti sospetti di violazione del copyright.