As variáveis ​​da sessão devem ser evitadas?

36

Eu costumava confiar muito em variáveis ​​de sessão no passado, mas recentemente descobri que muitas delas são desnecessárias, usando coisas como parâmetros de string de consulta.

Um colega meu se recusa a usar variáveis ​​de sessão. Esse é um objetivo realista e as variáveis ​​da sessão devem ser evitadas por qualquer motivo prático? As variáveis ​​de sessão podem ser completamente evitadas (exceto os cookies de sessão para permitir logins) e isso resultaria em melhores designs?

Alguns dos motivos pelos quais meu colega não os usou:

  • Natureza não digitada das variáveis ​​da sessão
  • Tempos limite da sessão causando perda de estado
  • Natureza do escopo global das variáveis ​​de sessão
  • Servidores de balanceamento de carga que perdem sessões (específico .Net?)
  • Pools / servidores de aplicativos reiniciando
  • Eles são desnecessários
Tjaart
fonte
3
using things like query string parameters instead- Neste caso, sempre use sempre os parâmetros da string de consulta, se possível. O uso da sessão para esse tipo de parâmetro é frágil e pode apresentar erros estranhos quando os usuários têm várias guias abertas.
Izkata
2
recomendação pessoal - não siga nenhum conselho do seu colega, pois ele claramente não sabe do que está falando. Tempos limite da sessão? Ele não percebe que as durações das sessões são controladas pelo aplicativo da web?
GrandmasterB
2
@GrandmasterB Ahem. Ou eles não sabem o que estão fazendo ou foram queimados por cada um desses pontos ao longo de sua carreira (eu mesmo atingi cerca de quatro deles) e conhece maneiras mais apropriadas de lidar com o estado temporário.
Ed James
Alguém poderia explicar a relação entre o estado da sessão e ter várias guias abertas? Quando você abre uma nova guia, ela contém ou agora o estado da guia anterior? Obrigado.
Ray

Respostas:

41

Se você tem uma variável de sessão em seu aplicativo, pergunte a si mesmo:

Quando clico no botão Voltar do meu navegador, que valor eu quero que minha variável tenha?

Se a resposta for "o valor atual", as variáveis ​​da sessão podem ser úteis. Um exemplo seria um carrinho de compras: você não espera que as coisas sejam removidas do carrinho de compras ao voltar ao histórico. Está sempre em seu estado atual.

Se a resposta for "um valor anterior", você não deve usar variáveis ​​de sessão. Os maus usos que vi incluem a passagem de um parâmetro entre as páginas. Se eu clicar no botão Voltar para retornar a uma página, a página não obterá necessariamente o parâmetro correto. Além disso, se eu abrir duas guias, como o meu site se comportará?

Consertar corretamente o comportamento do botão Voltar não é de jeito nenhum, mas ajuda você a pensar em um site como um aplicativo sem estado. Em geral, acho que os usos apropriados das variáveis ​​de sessão são poucos e distantes entre si.

Tim
fonte
Concordo. Depois de pensar na semântica desejada com várias guias, geralmente fica óbvio se as variáveis ​​da sessão ou os parâmetros de solicitação são a escolha certa.
CodesInChaos
Vi exatamente esses tipos de erros com variáveis ​​de sessão e reconhecidamente aprendi da maneira mais difícil.
TJart #
Quando um usuário pressiona o botão Voltar, ele espera que os itens permaneçam no carrinho de compras até que a sessão expire ou eles querem que os itens permaneçam até serem retirados? O uso de algum outro mecanismo de persistência (como um banco de dados) permitiria persistência além da sessão única e seu botão voltar ainda funcionaria como o usuário esperava.
Lawtonfogle 30/10
25

O protocolo HTTP é sem estado. As sessões são uma maneira de preservar o estado do cliente nas solicitações HTTP. Você pode optar por fazer isso com o tratamento de sessão interno de uma plataforma ou fazer você mesmo com os parâmetros da cadeia de caracteres de consulta. De qualquer maneira, é necessário algum conceito de sessão para muitas tarefas.

Seu colega provavelmente não gosta de uma implementação específica ou não está usando sessões para os fins pretendidos. Se você precisar reter informações sobre uma conexão específica do cliente através de solicitações HTTP, precisará de alguma forma de persistência da sessão.

Os seguintes problemas são específicos da implementação:

Natureza não digitada das variáveis ​​da sessão

Natureza do escopo global das variáveis ​​de sessão

Servidores de balanceamento de carga que perdem sessões

Pools / servidores de aplicativos reiniciando

Por exemplo, na maioria das vezes eu trabalho em PHP e armazeno minhas informações de sessão em um banco de dados relacional. Então, minhas variáveis ​​de sessão são digitadas. O balanceamento de carga e as reinicializações do servidor não causam problemas na sessão.

Este é mais interessante:

Tempos limite da sessão causando perda de estado

As sessões são mais frequentemente preservadas por meio de cookies. Estes podem ser excluídos pelo cliente a qualquer momento. Mas eles também podem ser preservados por meio de um parâmetro de sequência de consultas e, portanto, nunca atingem o tempo limite no cliente. O tempo limite do servidor depende de você. Portanto, mesmo esse problema é específico da implementação.

Não vamos jogar fora todo o conceito de sessões apenas porque não gostamos de uma implementação específica. Qualquer boa estrutura de aplicativo da Web facilitará o uso de sessões adequadamente para preservar logins do usuário ou reter qualquer outra coisa específica da visita atual do usuário. O registro do banco de dados de um usuário pode (e deve) ser usado para armazenar itens específicos a ele quando conectado. Os visitantes anônimos, no entanto, também podem ter informações temporárias que devem ser preservadas em sua sessão, como uma pequena lista de páginas recentes visitadas ou a preferência por esconda um aviso que eles já viram. Geralmente, apenas informações temporárias menores são apropriadas para o armazenamento da sessão.

Matt S
fonte
Para ser sincero, tive uma experiência limitada com frameworks além do .Net. O .Net pára de forçar um valor de tempo limite para suas sessões. As variáveis ​​de sessão também exibem o código do lado do servidor como um dicionário sem tipo. De qualquer maneira, costumo agrupar esse dicionário em classes adequadamente digitadas, portanto também não vejo isso como um problema. Você mencionou que armazena as informações da sua sessão no banco de dados. No ASP .Net, o armazenamento é tratado de outra forma, no cliente .Net, no banco de dados (gerenciado automaticamente) ou em um serviço Windows separado.
precisa saber é o seguinte
Você pode dar alguns exemplos dos propósitos pretendidos para as sessões?
Tjaart 15/08/12
@ Tjaart: eu expandi o último parágrafo um pouco. Espero que ajude.
Matt S
14

Outros fizeram muitos pontos positivos (que evitarei repetir), mas há um aspecto da técnica de seu amigo que ainda não foi discutido: segurança .

É impossível saber que tipo de vulnerabilidades você abre sem olhar para o código, mas aqui estão algumas coisas que eu posso pensar em cima da minha cabeça.

  • Fixação de sessão : um ataque poderoso que é um pouco mais fácil se você puder apenas fazer com que o usuário clique em um link que já tenha as informações necessárias na URL (em vez de tentar fazer com que o usuário use uma máquina com os cookies configurados adequadamente).
  • Injeção de SQL (ou outra entrada maliciosa) : nunca confie em nada que vem do usuário. As variáveis ​​de sessão têm a vantagem de nunca sair do servidor, portanto, o usuário não pode alterá-las diretamente. Embora você deva limpar os dados antes de colocá-los na sessão, sempre pode confiar nos valores que sairá depois. Se tudo for passado através da cadeia de consulta, você precisará validar MUITO para garantir que não está aceitando entrada maliciosa.
  • Corrupção de dados usando entradas falsificadas : Semelhante à injeção de SQL, quantos dados você está transmitindo? Quão crucial é isso? Posso alterar o comportamento do seu aplicativo alterando um valor na string de consulta? Posso corromper os dados no seu servidor alterando valores? Se eu conseguir corromper os dados no servidor, isso afetará outros usuários? (Se sua resposta foi "não", minha resposta é "você tem certeza? Você tem muitos lugares para verificar.").

Tudo isso ainda pode acontecer quando você usa Sessões, mas pode ficar muito mais fácil se o seu amigo não souber o que está fazendo.

riwalk
fonte
2

As variáveis ​​de sessão são como as antigas variáveis ​​globais básicas até certo ponto. O ônus é do usuário acompanhar, o que está neles, seu escopo e como são usados; assim como nas versões antigas do BASIC. Dito isto, por que alguém descartaria totalmente o uso de um mecanismo que obviamente é projetado para ser parte integrante e muito importante do modelo de programação (ASP, MVC etc.)?

A única coisa ruim em que me deparei com o uso de variáveis ​​de Sessão é que isso sobrecarrega você para acompanhá-las, garantir que elas sejam preenchidas com dados relevantes e descartá-las.

Não é isso que fazemos quando estamos programando alguma maneira?

Mac
fonte
1

Eu costumava pensar como seu colega devido a algumas experiências ruins que eu tive problemas de depuração relacionados a variáveis ​​de sessão, que eram realmente apenas incompetência da minha parte. Sim, você pode sobreviver, até certo ponto, sem variáveis ​​de sessão, usando cadeias de consulta, campos ocultos em formulários e outras coisas. No entanto, fica muito difícil fazê-lo dessa maneira, se seu aplicativo tiver algo além do fluxo lógico mais básico para determinar o estado. Há também o risco de segurança de mostrar o funcionamento interno do seu aplicativo por meio de cadeias de consulta e campos ocultos, qualquer um dos quais pode servir como vetores de ataque.

Ao trabalhar com variáveis ​​de sessão, você só precisa acompanhar quando elas são definidas e desabilitadas, pois isso determinará o fluxo lógico do aplicativo. É como o gerenciamento de memória em um idioma como C.

Observe que isso é apenas da minha experiência trabalhando com PHP em um projeto relativamente pequeno, sem estruturas, as coisas podem ser diferentes em outras plataformas, mas acho que o princípio geral ainda se aplica.

primehunter326
fonte
2
Como você obtém a semântica de várias guias corretamente ao usar sessões para o estado envolvido no seu fluxo de controle? As sessões funcionam bem para login e configurações como propriedades, mas não possuem a semântica correta para a maioria dos outros usos.
CodesInChaos
Não tenho certeza, o que postei foi baseado em minha própria experiência reconhecidamente limitada na criação de um aplicativo Web orientado a banco de dados em PHP / MySQL. Como são normalmente tratadas várias guias nos navegadores (suponho que você esteja se referindo a isso)?
primehunter326
@ primehunter326 Com parâmetros de rota ou cadeias de consulta ou campos de formulário ocultos.
Casey
0

Como indicado anteriormente, o HTTP é Stateless e a Session Variable quebra isso. O design do HTTP para ser sem estado ajuda a armazenar em cache os recursos. Para recursos disponíveis publicamente.

É possível criar um site sem variável de sessão, mas é mais difícil. O mais difícil (IMHO) é o sofisticado login / logout, os esquemas de autenticação HTTP não fornecem as ferramentas necessárias para autenticação através de um formulário HTML (você pode hackear algo com javascript - XHR para https: // untel: [email protected] ) e é ainda mais difícil sair e ser compatível com vários navegadores. houve alguma discussão nas listas de discussão do w3 sobre isso, mas se bem me lembro, a ideia foi descartada.

Quanto ao resto, você deve poder viver sem variáveis ​​de sessão. Você terá algum estado em um banco de dados, arquivos ou em qualquer lugar, mas o uso para variáveis ​​de sessão deve ser raro.

Se o seu usuário tiver um carrinho de compras, será uma sessão variável apenas se o usuário puder navegar em dois computadores / navegadores sem compartilhar o carrinho.

Mathieu
fonte