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

Análisis detallado del problema de expiración de sesión en .net mvc

Recientemente he estado investigando sobre el problema de la sesión expirada en proyectos de .net mvc, a continuación, compartiré el proceso de investigación con todos ustedes, pueden hacer referencia a él.

Recientemente resolví el problema de la sesión expirada en proyectos basados en .net mvc, me gustaría hablarles al respecto.

1Análisis de problemas

En .net mvc, cuando la sesión expira, es necesario considerar varias situaciones:

• Las acciones basadas en autenticación de permisos, utilizan solicitudes no Ajax

• Las acciones basadas en autenticación de permisos, utilizan solicitudes Ajax de JQuery

• Las acciones basadas en autenticación de permisos, utilizan solicitudes Ajax encapsuladas en .net mvc

• Las acciones sin autenticación de permisos, utilizan solicitudes no Ajax

• Las acciones sin autenticación de permisos, utilizan solicitudes Ajax nativas de JQuery

• Las acciones sin autenticación de permisos, utilizan solicitudes Ajax encapsuladas en .net mvc

Acción basada en autenticación de permisos, AuthorizeAttribute puede interceptar después de que la sesión expire y manejarla en el método HandleUnauthorizedRequest; las acciones sin autenticación de permisos deben estar en el filtro personalizado, donde se debe juzgar y manejar según la diferencia entre la sesión nueva y la sesión solicitada.

2Solicitud no Ajax basada en autenticación de permisos

El filtro de autorización se ejecuta antes que otros filtros de funcionalidad, por lo tanto, aquí se hereda AuthorizeAttribue y se maneja la solicitud de sesión en HandleUnauthorizedRequest.

public class AuthorizeOfHandleUnAuthorizeAttribute:AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//Redirigir a la página de inicio de sesión cuando la sesión caduque
filterContext.Result =
new RedirectToRouteResult(
new RouteValueDictionary(new { Controller = "Login", Action = "Login" }));
}
}

3.Solicitudes AJAX basadas en autenticación de permisos

Las acciones de solicitud AJAX en el sistema tienen dos tipos de resultados: JsonResult y PartialViewResult.

•Teóricamente, JsonResult se puede agregar una propiedad de sesión caducada en el resultado de retorno, y el cliente puede realizar el juicio. Pero teniendo en cuenta que el proyecto ya está terminado, agregar lógica de juicio en todas las solicitudes AJAX es un poco tedioso.

Código del servidor para manejar solicitudes AJAX:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//manejo de solicitudes AJAX de sesión caducada
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" }));
}

Código del cliente (este método de manejo no es aplicable a las acciones que devuelven PartialViewResult):

onSuccess: function (xhr, status) {
//Obtener encabezado de respuesta, sessionstatus,
var sessionstatus = xhr.getResponseHeader("sessionstatus");
if (sessionstatus == "timeout") {
window.location = "/Login/Login";
}
}

•La existencia de situations de PartialViewResult niega directamente la suposición anterior. La mayoría de las solicitudes Ajax del proyecto se basan en .net mvc encapsuladas, actualizando directamente el div especificado.

Para evitar hacer muchos cambios y manejar de manera uniforme dos tipos de resultados de solicitudes AJAX, se encontró otro método

jQuery.ajaxSetup()

Esta función se utiliza para cambiar las opciones de configuración predeterminadas de las solicitudes AJAX de jQuery. Todas las solicitudes AJAX ejecutadas después de esto, si no se han configurado los parámetros de opción correspondientes, usarán la configuración predeterminada modificada.

Por lo tanto, nuestro código de cliente puede manejar de manera uniforme así:

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

本以为到这里就万事大吉啦,结果一不小心又发现一个问题,基于.net mvc的jquery.unobtrusive-ajax封装的ajax请求调用,没有达到拦截处理的效果。经过反复调试无果,最终还是注意到上面那段话

jQuery.ajaxSetup()该函数用于更改jQuery中AJAX请求的默认设置选项。之后执行的所有AJAX请求,如果对应的选项参数没有设置,将使用更改后的默认设置。

这里说的比较明白了,那肯定就是jquery.unobtrusive-ajax封装的时候捣的鬼啦,翻开源码一看果然如此:

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

Las solicitudes de Ajax de Action sin autenticación de permisos pueden procesarse de la misma manera que las solicitudes de Action con autenticación de permisos mencionadas anteriormente, aquí no se pegará el código. Personalmente, siento que las solicitudes de Action sin autenticación de permisos generalmente no necesitan considerar la expiración de la sesión,因为这些 Action generalmente no obtienen información del session, solo realizan consultas de información pública.

5Problemas pendientes

Hasta aquí, el problema se resolvió básicamente, pero durante el proceso se encontró un problema misterioso, anótelo brevemente:

Originalmente, configuré el tiempo de expiración de la sesión muy corto en el archivo de configuración para simular la expiración de la sesión, pero descubrí que el marco del proyecto siempre cambiaba misteriosamente el tiempo de expiración de la sesión a60 minutos, no se encontró la razón. Más tarde, solo se pudo simular mediante la apertura de dos pestañas del mismo navegador, iniciando sesión en el sistema y simulando el método en una pestaña.

Lo mencionado anteriormente es el problema de expiración de sesión .NET MVC que el editor le ha presentado a todos, esperamos que sea útil para ustedes. Si tienen alguna pregunta, déjenos un mensaje y el editor responderá a tiempo. También agradecemos enormemente el apoyo de todos a la página web de呐喊教程!

Declaración: El contenido de este artículo se ha obtenido de la red, pertenece al propietario original, el contenido se ha contribuido y subido por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha procesado editorialmente por humanos ni asume ninguna responsabilidad legal relacionada. Si encuentra contenido sospechoso de infracción de derechos de autor, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, por favor reemplace # con @) para denunciar, y proporcione evidencia relevante. Una vez confirmado, este sitio eliminará inmediatamente el contenido sospechoso de infracción.

Te gustará