ASP.NET: Session.SessionID muda entre solicitações

142

Por que a propriedade SessionID no objeto Session em uma página ASP.NET é alterada entre solicitações?

Eu tenho uma página como esta:

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

E a saída continua mudando toda vez que eu clico em F5, independente do navegador.

Seb Nilsson
fonte

Respostas:

225

Esta é a razão

Ao usar o estado da sessão baseada em cookie, o ASP.NET não aloca armazenamento para dados da sessão até que o objeto Session seja usado. Como resultado, um novo ID de sessão é gerado para cada solicitação de página até que o objeto da sessão seja acessado. Se seu aplicativo exigir um ID de sessão estático para toda a sessão, você poderá implementar o método Session_Start no arquivo Global.asax do aplicativo e armazenar dados no objeto Session para corrigir o ID da sessão ou usar código em outra parte do seu aplicativo para armazenar explicitamente dados no objeto Session.

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

Então, basicamente, a menos que você acesse seu objeto de sessão no back-end, um novo sessionId será gerado com cada solicitação

EDITAR

Este código deve ser adicionado ao arquivo Global.asax. Ele adiciona uma entrada ao objeto Session para que você corrija a sessão até que ela expire.

protected void Session_Start(Object sender, EventArgs e) 
{
    Session["init"] = 0;
}
Claudio Redi
fonte
23
Eu não sabia que, nunca teve um problema com ele, mas que é interessante saber
Pharabus
1
O @Cladudio você pode simplesmente inserir uma linha de código e sua resposta é perfeita. Informações interessantes saindo de uma pergunta interessante ... mais uma? ;)
Seb Nilsson
2
Curiosamente, isso corrige meu problema - mas o problema só se manifestou após cerca de 6 meses de uso da base de código sem problemas. Não consigo pensar em nenhum motivo para isso ter mudado repentinamente - alguém pode sugerir um motivo pelo qual o sessionid repentinamente seria reiniciado quando não havia antes?
Moo
2
@KumarHarsh: depois de armazenar qualquer objeto na sessão, o ID da sessão será corrigido. Isso é o que eu quis dizer com "a menos que você acesse seu objeto de sessão no back-end ...". Depois de atribuir someida sessão, permanecerá o mesmo. Leve em consideração que esta resposta tem mais de 4 anos, não tenho certeza se houve alguma modificação em relação a isso.
Claudio Redi 13/10
9
Percebi que simplesmente adicionar o método Session_Start WITH NADA EM TI ao meu Global.asax fez esse trabalho. Obrigado @ Claudio pela dica.
Pedro
92

Há outro motivo, mais insidioso, por que isso pode ocorrer mesmo quando o objeto Session foi inicializado, como demonstrado pelo Cladudio.

No Web.config, se houver uma <httpCookies>entrada definida comorequireSSL="true" mas você não estiver usando HTTPS: para uma solicitação específica, o cookie da sessão não será enviado (ou talvez não seja retornado, não sei ao certo) o que significa que você acaba com uma nova sessão para cada solicitação.

Eu encontrei esse da maneira mais difícil, passando várias horas indo e voltando entre várias confirmações no meu controle de origem, até descobrir qual alteração específica havia quebrado o meu aplicativo.

Neville Cook
fonte
5
Eu sabia disso, mas continuo esquecendo a cada 3 meses mais ou menos e passo algumas horas depurando .. #
30516
No meu caso, eu estava testando no localhost e o "requireSSL" no web.config foi definido como "true". Obrigado.
William Pereira
esse foi o meu caso e passei muito tempo tentando descobrir (tinha um arenque vermelho com diferentes arquivos web.config).
precisa saber é
Sua sugestão acima ainda está ajudando em 2018. Esse é o cenário mais frequente. Obrigado!
Vijay Bansal
5

No meu caso, descobri que o cookie da sessão tinha um domínio que incluía www.prefixo, enquanto solicitava uma página sem www..
A adição www.ao URL imediatamente corrigiu o problema. Mais tarde, mudei o domínio do cookie para ser definido como em .mysite.comvez de www.mysite.com.

Kniganapolke
fonte
5

meu problema era que tínhamos esse conjunto no web.config

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

isso significa que, ao depurar em não SSL (o padrão), o cookie de autenticação não será enviado de volta ao servidor. isso significa que o servidor enviará um novo cookie de autenticação (com uma nova sessão) para cada solicitação de volta ao cliente.

a correção é definir o requiressl como false no web.config e true no web.release.config ou ativar o SSL durante a depuração:

ativar SSL

Josh
fonte
Como isso é diferente da resposta de Neville Cook de 2011?
22618 Ian Kemp
4

Usando a resposta de Neville (excluindo requireSSL = true, em web.config) e modificando levemente o código de Joel Etherton, eis o código que deve lidar com um site que é executado no modo SSL e não SSL, dependendo do usuário e da página (I estou voltando ao código e ainda não o testei no SSL, mas espero que funcione - estará muito ocupado mais tarde para voltar a isso, então aqui 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
fonte
2

Outra possibilidade que faz com que o SessionID mude entre solicitações, mesmo quando Session_OnStart é definido e / ou uma Sessão foi inicializada, é que o nome do host da URL contenha um caractere inválido (como um sublinhado). Acredito que isso seja específico do IE (não verificado), mas se o seu URL for, digamos, o http://server_name/appIE bloqueará todos os cookies e as informações da sua sessão não estarão acessíveis entre solicitações.

De fato, cada solicitação gerará uma sessão separada no servidor; portanto, se sua página contiver várias imagens, tags de script, etc., cada uma dessas solicitações GET resultará em uma sessão diferente no servidor.

Mais informações: http://support.microsoft.com/kb/316112

R. Aaron Zupancic
fonte
2

No meu caso, isso estava acontecendo muito nos meus ambientes de desenvolvimento e teste. Depois de tentar todas as soluções acima sem sucesso, descobri que era possível corrigir esse problema excluindo todos os cookies de sessão. A extensão do desenvolvedor da web facilita muito isso. Eu uso principalmente o Firefox para testes e desenvolvimento, mas isso também aconteceu durante os testes no Chrome. A correção também funcionou no Chrome.

Ainda não precisei fazer isso no ambiente de produção e não recebi nenhum relatório de pessoas que não conseguiam fazer login. Isso também pareceu acontecer depois de tornar os cookies da sessão seguros. Isso nunca aconteceu no passado quando eles não estavam seguros.

Matt L
fonte
Atualização: isso só começou a acontecer depois que alteramos o cookie da sessão para torná-lo seguro. Determinamos que o problema exato foi causado por haver dois ou mais cookies de sessão no navegador com o mesmo caminho e domínio. O que sempre foi o problema foi o que tinha um valor vazio ou nulo. Depois de excluir esse cookie específico, o problema foi resolvido. Também adicionei código no método Global.asax.cs Sessin_Start para verificar esse cookie vazio e, em caso afirmativo, defina a data de validade como algo no passado.
Matt L
2

no meu caso, foi porque eu estava modificando a sessão após o redirecionamento de um gateway em um aplicativo externo ; portanto, porque estava usando o IP no host local naquela URL da página, na verdade era considerado site diferente com sessões diferentes.

Em suma

preste mais atenção se estiver depurando um aplicativo hospedado no IIS em vez do IIS express e misturando sua máquina http: // Ip e http: // localhost em várias páginas

Iman
fonte
1

Meu problema foi com um aplicativo IPTV do Microsoft MediaRoom. Acontece que os aplicativos MRF MPF não suportam cookies; mudar para usar sessões sem cozinhar na web.config resolveu meu problema

<sessionState cookieless="true"  />

Aqui está um artigo MUITO antigo: Cookieless ASP.NET

denvercoder9
fonte
1

Estou no .NET Core 2.1 e estou ciente de que a pergunta não é sobre o Core. No entanto, a internet está faltando e o Google me trouxe aqui, esperando salvar alguém por algumas 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 };
        }
    }
}

Observe que a sessão de gravação e leitura funciona, mas nenhum cookie parece ser passado para o navegador. Pelo menos não consegui encontrar um cabeçalho "Set-Cookie" em lugar nenhum.

Krivar
fonte
0

Certifique-se de que você não tenha um tempo limite de sessão muito curto e também se estiver usando sessões baseadas em cookies que esteja aceitando a sessão.

A barra de ferramentas do FireFox webDeveloperTool é útil em momentos como esse, pois você pode ver os cookies definidos para o seu aplicativo.

Mitchel Sellers
fonte
2
Acho que o tempo limite da minha sessão não está definido para menos de um segundo. Ele muda a cada rápida impressão F5.
Seb Nilsson
0

A redefinição do ID da sessão pode ter várias causas. No entanto, qualquer um dos mencionados acima não se relaciona com o meu problema. Então eu vou descrevê-lo para referência futura.

No meu caso, uma nova sessão criada em cada solicitação resultou em um loop de redirecionamento infinito. A ação de redirecionamento ocorre no evento OnActionExecuting .

Também estive limpando todos os cabeçalhos http (também no evento OnActionExecuting usando Response.ClearHeaders método ) para evitar o cache de sites no lado do cliente. Mas esse método limpa todos os cabeçalhos, incluindo informações sobre a sessão do usuário e, consequentemente, todos os dados no armazenamento Temp (que eu estava usando posteriormente no programa). Portanto, mesmo a configuração de nova sessão no evento Session_Start não ajudou.

Para resolver meu problema, assegurei-me de não remover os cabeçalhos quando ocorrer um redirecionamento.

Espero que ajude alguém.

user3253726
fonte
0

Encontrei esta questão de uma maneira diferente. Os controladores que tinham esse atributo [SessionState(SessionStateBehavior.ReadOnly)]estavam lendo de uma sessão diferente, embora eu tenha definido um valor na sessão original na inicialização do aplicativo. Eu estava adicionando o valor da sessão através do _layout.cshtml (talvez não seja a melhor ideia?)

Foi claramente o ReadOnly que causou o problema, porque quando removi o atributo, a sessão original (e o SessionId) permaneceriam intactos. Usando a solução de Claudio / Microsoft, foi corrigido.

goku_da_master
fonte