ASP.NET: Session.SessionID cambia entre solicitudes

142

¿Por qué la propiedad SessionID en el objeto Session en una página ASP.NET cambia entre solicitudes?

Tengo una página como esta:

...
<div>
    SessionID: <%= SessionID %>
</div>
...

Y la salida sigue cambiando cada vez que presiono F5, independientemente del navegador.

Seb Nilsson
fuente

Respuestas:

225

Esta es la razón

Cuando se usa el estado de sesión basado en cookies, ASP.NET no asigna almacenamiento para los datos de la sesión hasta que se usa el objeto Session. Como resultado, se genera una nueva ID de sesión para cada solicitud de página hasta que se accede al objeto de sesión. Si su aplicación requiere una ID de sesión estática para toda la sesión, puede implementar el método Session_Start en el archivo Global.asax de la aplicación y almacenar datos en el objeto Session para corregir la ID de sesión, o puede usar el código en otra parte de su aplicación para almacenar explícitamente datos en el objeto Session.

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx

Básicamente, a menos que acceda a su objeto de sesión en el backend, se generará un nuevo Id. De sesión con cada solicitud

EDITAR

Este código debe agregarse en el archivo Global.asax. Agrega una entrada al objeto Sesión para que arregle la sesión hasta que caduque.

protected void Session_Start(Object sender, EventArgs e) 
{
    Session["init"] = 0;
}
Claudio Redi
fuente
23
No lo sabía, nunca tuve un problema con eso, pero es interesante saberlo
Pharabus
1
@Cladudio, ¿podría simplemente agregar una línea de código y su respuesta es perfecta? Información interesante que surge de una pregunta interesante ... ¿más una? ;)
Seb Nilsson
2
Curiosamente, esto soluciona mi problema, pero el problema solo se manifestó después de aproximadamente 6 meses de usar el código base sin ningún problema. No se me ocurre ninguna razón por la que esto hubiera cambiado repentinamente. ¿Alguien puede sugerir una razón por la cual el sessionid se restablecería de repente cuando no lo había hecho antes?
Moo
2
@ KumarHarsh: una vez que almacene cualquier objeto en la sesión, la identificación de la sesión será reparada. Eso es lo que quise decir con "a menos que acceda a su objeto de sesión en el back-end ...". Una vez que asigne someidla sesión, seguirá siendo la misma. Tenga en cuenta que esta respuesta tiene más de 4 años, no estoy seguro de si hubo alguna modificación en relación con esto.
Claudio Redi
9
Noté que simplemente agregando el método Session_Start SIN NADA EN ELLO a mi Global.asax hizo que esto funcionara. Sin embargo, gracias @Claudio por el consejo.
Pedro
92

Hay otra razón más insidiosa por la que esto puede ocurrir incluso cuando el objeto Session se ha inicializado como lo demuestra Cladudio.

En Web.config, si hay una <httpCookies>entrada establecida requireSSL="true"pero no está utilizando HTTPS: para una solicitud específica, la cookie de sesión no se envía (o tal vez no se devuelve, no estoy seguro de qué) lo que significa que terminas con una nueva sesión para cada solicitud.

Encontré esto de la manera difícil, pasando varias horas yendo y viniendo entre varias confirmaciones en mi control de origen, hasta que descubrí qué cambio específico había roto mi aplicación.

Neville Cook
fuente
55
Yo sabía esto, pero todavía lo olvido cada 3 meses o así, y pasar un par de horas de depuración ..
sotn
En mi caso, estaba probando en localhost y el "requireSSL" en web.config se configuró como "verdadero". Gracias.
William Pereira
este fue mi caso, y pasé demasiado tiempo tratando de resolverlo (tenía un arenque rojo con diferentes archivos web.config).
jmoreno
Su sugerencia anterior sigue siendo útil en 2018. Este es el escenario más frecuente. ¡Gracias!
Vijay Bansal
5

En mi caso, descubrí que la cookie de sesión tenía un dominio que incluía el www.prefijo, mientras solicitaba la página sin www..
Agregar www.a la URL solucionó el problema de inmediato. Más tarde cambié el dominio de la cookie para configurarlo en .mysite.comlugar de www.mysite.com.

Kniganapolke
fuente
5

mi problema fue que teníamos esto configurado en web.config

<httpCookies httpOnlyCookies="true" requireSSL="true" />

Esto significa que al depurar en un sistema que no sea SSL (el valor predeterminado), la cookie de autenticación no se devolverá al servidor. Esto significaría que el servidor enviaría una nueva cookie de autenticación (con una nueva sesión) para cada solicitud de vuelta al cliente.

la solución es establecer requiressl en falso en web.config y verdadero en web.release.config o activar SSL durante la depuración:

activar SSL

josh
fuente
¿Cómo es esto diferente a la respuesta de Neville Cook de 2011?
Ian Kemp
4

Usando la respuesta de Neville (eliminando requireSSL = true, en web.config) y modificando ligeramente el código de Joel Etherton, aquí está el código que debe manejar un sitio que se ejecuta tanto en modo SSL como en modo no SSL, dependiendo del usuario y la página (I Estoy volviendo al código y aún no lo he probado en SSL, pero espero que funcione, estará demasiado ocupado más tarde para volver a esto, así que aquí está:

if (HttpContext.Current.Response.Cookies.Count > 0)
        {
            foreach (string s in HttpContext.Current.Response.Cookies.AllKeys)
            {
                if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
                {
                    HttpContext.Current.Response.Cookies[s].Secure = HttpContext.Current.Request.IsSecureConnection;
                }
            }
        }
Reid
fuente
2

Otra posibilidad que hace que el SessionID cambie entre solicitudes, incluso cuando se define Session_OnStart y / o se ha inicializado una sesión, es que el nombre de host de la URL contiene un carácter no válido (como un guión bajo). Creo que esto es específico de IE (no verificado), pero si su URL es, digamos http://server_name/app, entonces IE bloqueará todas las cookies y su información de sesión no será accesible entre las solicitudes.

De hecho, cada solicitud activará una sesión separada en el servidor, por lo que si su página contiene múltiples imágenes, etiquetas de script, etc., cada una de esas solicitudes GET dará como resultado una sesión diferente en el servidor.

Más información: http://support.microsoft.com/kb/316112

R. Aaron Zupancic
fuente
2

En mi caso, esto estaba sucediendo mucho en mis entornos de desarrollo y prueba. Después de probar todas las soluciones anteriores sin ningún éxito, descubrí que podía solucionar este problema eliminando todas las cookies de sesión. La extensión de desarrollador web hace que esto sea muy fácil de hacer. Principalmente uso Firefox para pruebas y desarrollo, pero esto también sucedió durante las pruebas en Chrome. La solución también funcionó en Chrome.

Todavía no he tenido que hacer esto en el entorno de producción y no he recibido ningún informe de personas que no puedan iniciar sesión. Esto también parece suceder después de que las cookies de sesión sean seguras. Nunca sucedió en el pasado cuando no estaban seguros.

Matt L
fuente
Actualización: esto solo comenzó a suceder después de que cambiamos la cookie de sesión para que sea segura. He determinado que el problema exacto fue causado por la existencia de dos o más cookies de sesión en el navegador con la misma ruta y dominio. El que siempre fue el problema fue el que tenía un valor vacío o nulo. Después de eliminar esa cookie en particular, el problema se resolvió. También he agregado código en el método Global.asax.cs Sessin_Start para verificar esta cookie vacía y, si es así, establecer su fecha de vencimiento en algo en el pasado.
Matt L
2

en mi caso fue porque estaba modificando la sesión después de redirigir desde una puerta de enlace en una aplicación externa , por lo que debido a que estaba usando IP en lugar de localhost en esa url de la página, en realidad se consideraba un sitio web diferente con diferentes sesiones.

En resumen

preste más atención si está depurando una aplicación alojada en IIS en lugar de IIS express y mezclando su máquina http: // Ip y http: // localhost en varias páginas

Iman
fuente
1

Mi problema fue con una aplicación IPTV de Microsoft MediaRoom. Resulta que las aplicaciones MPF MRML no admiten cookies; cambiar para usar sesiones sin cookies en la web.config resolvió mi problema

<sessionState cookieless="true"  />

Aquí hay un artículo REALMENTE antiguo al respecto: ASP.NET sin cookies

denvercoder9
fuente
1

Estoy en .NET Core 2.1 y soy consciente de que la pregunta no se trata de Core. Sin embargo, falta Internet y Google me trajo aquí, con la esperanza de salvar a alguien unas horas.


Startup.cs

services.AddCors(o => o.AddPolicy("AllowAll", builder =>
            {
                builder
                    .WithOrigins("http://localhost:3000")     // important
                    .AllowCredentials()                       // important
                    .AllowAnyMethod()
                    .AllowAnyHeader();       // obviously just for testing
            }));

client.js

const resp = await fetch("https://localhost:5001/api/user", {
            method: 'POST',
            credentials: 'include',                           // important
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        })

Controllers/LoginController.cs

namespace WebServer.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        [HttpPost]
        public IEnumerable<string> Post([FromBody]LoginForm lf)
        {
            string prevUsername = HttpContext.Session.GetString("username");
            Console.WriteLine("Previous username: " + prevUsername);

            HttpContext.Session.SetString("username", lf.username);

            return new string[] { lf.username, lf.password };
        }
    }
}

Tenga en cuenta que la sesión de escritura y lectura funciona, sin embargo, no parece que se pasen cookies al navegador. Al menos no pude encontrar un encabezado "Set-Cookie" en ningún lado.

krivar
fuente
0

Asegúrese de no tener un tiempo de espera de sesión que sea muy corto, y también asegúrese de que si está utilizando sesiones basadas en cookies, está aceptando la sesión.

La barra de herramientas webDeveloperTool de FireFox es útil en momentos como este, ya que puede ver las cookies establecidas para su aplicación.

Mitchel Sellers
fuente
2
Supongo que el tiempo de espera de mi sesión no está configurado por debajo de un segundo. Cambia con cada pulsación rápida de F5.
Seb Nilsson
0

El restablecimiento de ID de sesión puede tener muchas causas. Sin embargo, cualquiera de los mencionados anteriormente no se relaciona con mi problema. Así que lo describiré para referencia futura.

En mi caso, una nueva sesión creada en cada solicitud resultó en un bucle de redireccionamiento infinito. La acción de redireccionamiento tiene lugar en el evento OnActionExecuting .

También he estado borrando todos los encabezados http (también en el evento OnActionExecuting usando el método Response.ClearHeaders ) para evitar el almacenamiento en caché de sitios en el lado del cliente. Pero ese método borra todos los encabezados, incluida la información sobre la sesión del usuario y, en consecuencia, todos los datos en el almacenamiento temporal (que estaba usando más adelante en el programa). Entonces, incluso configurar una nueva sesión en el evento Session_Start no ayudó.

Para resolver mi problema, me aseguré de no eliminar los encabezados cuando se produce una redirección.

Espero que ayude a alguien.

usuario3253726
fuente
0

Me encontré con este problema de una manera diferente. Los controladores que tenían este atributo [SessionState(SessionStateBehavior.ReadOnly)]estaban leyendo desde una sesión diferente a pesar de que había establecido un valor en la sesión original al iniciar la aplicación. Estaba agregando el valor de la sesión a través de _layout.cshtml (¿tal vez no sea la mejor idea?)

Claramente fue el ReadOnly el que causó el problema porque cuando eliminé el atributo, la sesión original (y SessionId) se mantendrían intactas. El uso de la solución de Claudio / Microsoft lo arregló.

goku_da_master
fuente