web-dev-qa-db-fra.com

ASP.NET: Session.SessionID change entre les demandes

Pourquoi la propriété SessionID de l'objet Session - d'une page ASP.NET change-t-elle entre les requêtes?

J'ai une page comme celle-ci:

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

Et la sortie ne cesse de changer à chaque fois que j'appuie sur F5, quel que soit le navigateur.

123
Seb Nilsson

C'est la raison

Lors de l'utilisation d'un état de session basé sur un cookie, ASP.NET n'alloue pas de stockage pour les données de session tant que l'objet Session n'est pas utilisé. En conséquence, un nouvel ID de session est généré pour chaque demande de page jusqu'à l'accès à l'objet de session. Si votre application nécessite un ID de session statique pour l'ensemble de la session, vous pouvez implémenter la méthode Session_Start dans le fichier Global.asax de l'application et stocker les données dans l'objet Session pour corriger l'ID de session ou vous pouvez utiliser du code dans une autre partie de votre. application pour stocker explicitement les données dans l'objet Session.

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

Donc, fondamentalement, à moins que vous n'accédiez à votre objet de session sur le backend, un nouvel identificateur de session sera généré avec chaque requête.

MODIFIER

Ce code doit être ajouté au fichier Global.asax. Il ajoute une entrée à l'objet Session afin que vous corrigiez la session jusqu'à son expiration.

protected void Session_Start(Object sender, EventArgs e) 
{
    Session["init"] = 0;
}
198
Claudio Redi

Il existe une autre raison, plus insidieuse, pour laquelle cela peut se produire même lorsque l'objet Session a été initialisé, comme illustré par Cladudio.

Dans Web.config, si une entrée <httpCookies> est définie sur requireSSL="true" mais que vous n'utilisez pas réellement HTTPS: pour une demande spécifique, le cookie de session n'est pas envoyé (ou peut-être pas renvoyé, je ne sais pas laquelle). ce qui signifie que vous vous retrouvez avec une toute nouvelle session pour chaque demande.

J'ai trouvé celui-ci à la dure, passant plusieurs heures entre plusieurs commits dans mon contrôle de source, jusqu'à ce que je découvre quel changement spécifique avait cassé mon application.

84
Neville Cook

Dans mon cas, j'ai découvert que le cookie de session avait un domain qui comprenait le préfixe www., alors que je demandais une page sans www..
L'ajout de www. à l'URL a immédiatement résolu le problème. Plus tard, j'ai modifié le domaine du cookie afin qu'il soit défini sur .mysite.com au lieu de www.mysite.com.

5
Kniganapolke

En utilisant la réponse de Neville (suppression de requireSSL = true, dans web.config) et modifiant légèrement le code de Joel Etherton, voici le code devant gérer un site fonctionnant en mode SSL ou non, en fonction de l'utilisateur et la page (je retourne dans le code et je ne l'ai pas encore testé sur SSL, mais attendez-vous à ce qu'il fonctionne - il sera trop occupé ultérieurement pour y revenir, alors voici:

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;
                }
            }
        }
3
Reid

Une autre possibilité qui fait que l'identificateur de session change entre les demandes, même lorsque Session_OnStart est définie et/ou qu'une session a été initialisée, est que l'URL nom d'hôte contient un caractère non valide (tel qu'un trait de soulignement). Je pense que ceci est IE spécifique (non vérifié), mais si votre URL est, par exemple, http://server_name/app, alors IE bloquera tous les cookies et vos informations de session ne seront pas accessibles entre les demandes.

En fait, chaque demande crée une session distincte sur le serveur. Par conséquent, si votre page contient plusieurs images, balises de script, etc., chacune de ces demandes GET donnera lieu à une session différente sur le serveur.

Informations complémentaires: http://support.Microsoft.com/kb/316112

2
R. Aaron Zupancic

mon problème était que nous avions cet ensemble dans web.config 

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

cela signifie que lors du débogage en mode non-SSL (par défaut), le cookie d'authentification ne serait pas renvoyé au serveur. cela signifierait que le serveur enverrait un nouveau cookie d'authentification (avec une nouvelle session) pour chaque demande au client.

le correctif consiste soit à définir requiressl sur false dans web.config et sur true dans web.release.config ou d'activer SSL lors du débogage:

 turn on SSL

1
josh

Mon problème était avec une application IPTV Microsoft MediaRoom. Il s'avère que les applications MPF MRML ne prennent pas en charge les cookies. changer pour utiliser des sessions sans cookie dans le web.config a résolu mon problème

<sessionState cookieless="true"  />

Voici un article VRAIMENT ancien à ce sujet: Cookieless ASP.NET

1
denvercoder9

Dans mon cas, cela se produisait souvent dans mes environnements de développement et de test. Après avoir essayé toutes les solutions ci-dessus sans succès, j'ai constaté que je pouvais résoudre ce problème en supprimant tous les cookies de session. L'extension développeur Web rend cela très facile à faire. J'utilise principalement Firefox pour les tests et le développement, mais cela s'est également produit lors des tests dans Chrome. Le correctif a également fonctionné dans Chrome.

Je n'ai pas encore eu à le faire dans l'environnement de production et je n'ai reçu aucun rapport signalant que des personnes ne pouvaient pas se connecter. Cela semblait également se produire après la sécurisation des cookies de session. Cela n’est jamais arrivé dans le passé quand ils n’étaient pas en sécurité.

1
Matt L

dans mon cas, c’était parce que je modifiais la session après la redirection à partir d’une passerelle dans une application externe. Par conséquent, comme j’utilisais IP au lieu de localhost dans cette URL de page, ce site était considéré comme différent avec des sessions différentes.

En résumé 

faites plus attention si vous déboguez une application hébergée sur IIS au lieu de IIS express et mélangez votre ordinateur http: // Ip et http: // localhost dans diverses pages

1
Iman Abidi

Assurez-vous de ne pas avoir un délai d'expiration de session très court. Assurez-vous également que si vous utilisez des sessions basées sur des cookies, vous acceptez la session.

La barre Web FireFox WebDeveloperToolbar est utile, car vous pouvez voir les cookies configurés pour votre application.

0
Mitchel Sellers

Je suis sur .NET Core 2.1 et je sais bien que la question ne concerne pas Core. Pourtant, Internet manque et Google m'a amené ici dans l'espoir de sauver quelqu'un quelques heures.


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

Notez que l'écriture et la lecture de session fonctionnent, mais aucun cookie ne semble avoir été transmis au navigateur. Au moins, je n'ai trouvé aucun en-tête "Set-Cookie".

0
krivar

La réinitialisation de l'identifiant de session peut avoir plusieurs causes. Cependant, tout ce qui est mentionné ci-dessus ne concerne pas mon problème. Je vais donc le décrire pour référence future.

Dans mon cas, une nouvelle session créée à chaque demande a entraîné une boucle de redirection infinie. L'action de redirection a lieu dans OnActionExecuting event.

En outre, j'ai effacé tous les en-têtes http (également dans OnActionExecuting event à l'aide de Response.ClearHeaders method) afin d'empêcher la mise en cache des sites côté client. Mais cette méthode efface tous les en-têtes, y compris les informations sur la session de l'utilisateur, et par conséquent toutes les données du stockage temporaire (que j'utilisais plus tard dans le programme). Donc, même définir une nouvelle session dans l'événement Session_Start n'a pas aidé.

Pour résoudre mon problème, je me suis assuré de ne pas supprimer les en-têtes lors d'une redirection.

J'espère que ça aide quelqu'un.

0
user3253726

J'ai rencontré ce problème d'une manière différente. Les contrôleurs qui avaient cet attribut [SessionState(SessionStateBehavior.ReadOnly)] lisaient à partir d'une session différente même si j'avais défini une valeur dans la session d'origine au démarrage de l'application. J'ajoutais la valeur de session via _layout.cshtml (peut-être pas la meilleure idée?)

Il s'agissait clairement du problème ReadOnly car, lorsque j'ai supprimé l'attribut, la session d'origine (et SessionId) restait intacte. L'utilisation de la solution de Claudio/Microsoft a résolu le problème.

0
goku_da_master