PHP:$_SESSION - Quais são os prós e os contras de armazenar dados usados ​​temporariamente na variável $_SESSION

StackOverflow https://stackoverflow.com/questions/77826

  •  09-06-2019
  •  | 
  •  

Pergunta

Uma coisa que comecei a fazer com mais frequência recentemente é recuperando alguns dados no início de uma tarefa e armazená-lo em um $_SESSION['myDataForTheTask'].

Agora parece muito conveniente fazer isso, mas não sei nada sobre desempenho, riscos de segurança ou similares, usando esta abordagem.É algo que é feito regularmente por programadores com mais experiência ou é algo mais amador?

Por exemplo:

if (!isset($_SESSION['dataentry']))
{
    $query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=" . mysql_real_escape_string($_GET['wave_id']);
    $result_taskinfo = $db->query($query_taskinfo);
    $row_taskinfo = $result_taskinfo->fetch_row();

        $dataentry = array("pcode" => $row_taskinfo[0], "modules" => $row_taskinfo[1], "data_id" => 0, "wavenum" => $row_taskinfo[2], "prequest" => FALSE, "highlight" => array());

        $_SESSION['dataentry'] = $dataentry;
}
Foi útil?

Solução

Bem, as variáveis ​​de sessão são realmente uma das únicas maneiras (e provavelmente a mais eficiente) de ter essas variáveis ​​disponíveis durante todo o tempo que o visitante estiver no site, não há nenhuma maneira real de um usuário editá-las (além de uma exploração em seu código ou no interpretador PHP) para que sejam bastante seguros.

É uma boa maneira de armazenar configurações que podem ser alteradas pelo usuário, pois você pode ler as configurações do banco de dados uma vez no início de uma sessão e está disponível para toda a sessão, você só precisa fazer novas chamadas ao banco de dados se as configurações são alteradas e claro, como você mostra no seu código, é trivial descobrir se as configurações já existem ou se precisam ser extraídas do banco de dados.

Não consigo pensar em nenhuma outra maneira de armazenar variáveis ​​temporárias com segurança (já que os cookies podem ser facilmente modificados e isso será indesejável na maioria dos casos), então $_SESSION seria a melhor opção

Outras dicas

O mecanismo $_SESSION está usando cookies.

No caso do Firefox (e talvez do novo IE, eu não verifiquei), isso significa que sessão é compartilhada entre abas abertas.Isso não é algo que você espera por padrão.E isso significa que a sessão não é mais "algo específico para uma única janela/usuário".

Por exemplo, se você abriu duas abas para acessar seu site, e depois se conectou como root usando a primeira aba, você ganhará privilégios de root na outra.

Isso é realmente inconveniente, especialmente se você codifica um cliente de e-mail ou qualquer outra coisa (como e-shop).Neste caso você terá que gerenciar as sessões manualmente ou introduzir uma chave regenerada constantemente na URL ou fazer outra coisa.

Eu uso a variável de sessão o tempo todo para armazenar informações dos usuários.Não vi nenhum problema com desempenho.Os dados da sessão são extraídos com base no cookie (ou PHPSESSID se você tiver os cookies desativados).Não vejo isso como um risco de segurança maior do que qualquer outra autenticação baseada em cookie e provavelmente mais seguro do que armazenar os dados reais no cookie do usuário.

Só para você saber, você tem um problema de segurança com sua instrução SQL:

SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".$_GET['wave_id'];

Você deve NUNCA, REPITO NUNCA, pegue os dados fornecidos pelo usuário e use-os para executar uma instrução SQL sem primeiro limpá-la.Eu colocaria entre aspas e adicionaria a função mysql_real_escape_string().Isso irá protegê-lo da maioria dos ataques.Então sua linha ficaria assim:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id='".mysql_real_escape_string($_GET['wave_id'])."'";

Existem alguns fatores que você deve considerar ao decidir onde armazenar dados temporários.O armazenamento de sessão é ótimo para dados específicos de um único usuário.Se você achar que o manipulador de armazenamento de sessão baseado em arquivo padrão é ineficiente, você pode implementar outra coisa, possivelmente usando um banco de dados ou tipo de back-end memcache.Ver session_set_save_handler para mais informações.

Acho que é uma má prática armazenar dados comuns na sessão de um usuário.Existem locais melhores para armazenar dados que serão acessados ​​frequentemente por vários usuários e ao armazenar esses dados na sessão você estará duplicando os dados para cada usuário que necessita desses dados.No seu exemplo, você pode configurar um tipo diferente de mecanismo de armazenamento para esses dados de onda (com base em wave_id) que NÃO esteja vinculado especificamente à sessão de um usuário.Dessa forma, você extrairá os dados uma vez e os armazenará em algum lugar onde vários usuários possam acessar os dados sem precisar de outra extração.

Se você estiver executando em seu próprio servidor ou em um ambiente onde ninguém possa espionar seus arquivos/memória no servidor, os dados da sessão estarão seguros.Eles são armazenados no servidor e apenas um cookie de identificação enviado ao cliente.O problema é que outras pessoas possam roubar o biscoito e se passar por outra pessoa, é claro.Usar HTTPS e certificar-se de não colocar o ID da sessão em URLs deve manter seus usuários protegidos da maioria desses problemas.(XSS ainda pode ser usado para capturar cookies se você não tomar cuidado, consulte Jeef Atwoods postou sobre isso também.)

Quanto ao que armazenar em uma variável de sessão, coloque seus dados lá se quiser consultá-los novamente em outra página, como um carrinho de compras, mas não coloque lá se forem apenas dados temporários usados ​​para produzir o resultado desta página, como uma lista de tags para a postagem visualizada no momento.As sessões são para dados persistentes por usuário.

Outra forma de melhorar a validação de entrada é converter a variável _GET['wave_id']:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".(int)$_GET['wave_id']." LIMIT 1";

Presumo que wave_id seja um número inteiro e que haja apenas uma resposta.

Vai

Algumas outras desvantagens de usar sessões:

  1. $_SESSION os dados expirarão após sessão.gc_maxlifetime segundos de inatividade.
  2. Você terá que se lembrar de ligar session_start() para cada script que usará os dados da sessão.
  3. Dimensionar o site por meio do balanceamento de carga em vários servidores pode ser um problema porque o usuário precisará ser direcionado sempre para o mesmo servidor.Resolva isso com "Sticky Sessions".

Os itens $_SESSION são armazenados na sessão, que é, por padrão, mantida em disco.Não há necessidade de criar seu próprio array e colocá-lo em uma entrada de array de 'entrada de dados' como você fez.Você pode apenas usar $_SESSION['pcode'], $_SESSION['modules'] e assim por diante.

Como eu disse, a sessão é armazenada em disco e um ponteiro para a sessão é armazenado em um cookie.O usuário, portanto, não consegue obter facilmente os dados da sessão.

IMO, é perfeitamente aceitável armazenar coisas na sessão.É uma ótima maneira de tornar os dados persistentes.Também é, em muitos casos, mais seguro do que armazenar tudo em cookies.Aqui estão algumas preocupações:

  • É possível que alguém sequestre uma sessão, portanto, se você for usá-la para monitorar a autorização do usuário, tome cuidado.Ler esse Para maiores informações.
  • Pode ser uma maneira muito preguiçosa de manter dados.Não jogue tudo na sessão para não precisar consultá-la mais tarde.
  • Se você for armazenar objetos na sessão, seus arquivos de classe precisarão ser incluídos antes da sessão ser iniciada na próxima solicitação ou você precisará ter configurado um carregador automático.

Zend Framework possui uma biblioteca útil para gerenciamento de dados de sessão que ajuda com expiração e segurança (para coisas como captchas).Eles também têm uma explicação útil das sessões.Ver http://framework.zend.com/manual/en/zend.session.html

Achei as sessões muito úteis, mas algumas coisas devem ser observadas:

1) Que o PHP possa armazenar suas sessões em uma pasta tmp ou outro diretório que possa ser acessível a outros usuários em seu servidor.Você pode alterar o diretório onde as sessões são armazenadas acessando o arquivo php.ini.

2) Se você estiver configurando um sistema de alto valor que precisa de segurança muito rígida, talvez você queira criptografar os dados antes de enviá-los para a sessão e descriptografá-los para usá-los.Observação:isso pode criar muita sobrecarga dependendo da capacidade do tráfego/servidor.

3) Descobri que session_destroy();não exclui a sessão imediatamente, você ainda terá que esperar que o coletor de lixo do PHP limpe as sessões.Você pode alterar a frequência com que o coletor de lixo é executado no arquivo php.ini.Mas ainda não parece muito confiável, mais informações http://www.captain.at/howto-php-sessions.php

Você pode querer considerar o quão REST é isso?

ou sejaconsulte o parágrafo "Comunicar-se sem apátrida" em "Uma breve introdução ao REST"...

"O restante exige que o Estado seja transformado em estado de recursos ou mantido no cliente.Em outras palavras, um servidor não deve ter que manter algum tipo de estado de comunicação para qualquer um dos clientes com quem se comunica além de uma única solicitação ".

(ou qualquer outro link na Wikipédia para DESCANSAR)

Então, no seu caso, o 'wave_id' é um recurso sensato para GET, mas você realmente deseja armazená-lo na SESSÃO?Certamente memcached é a sua solução para armazenar em cache o recurso do objeto?

Eu uso bastante essa abordagem, não vejo nenhum problema com ela.Ao contrário dos cookies, os dados não são armazenados no lado do cliente, o que muitas vezes é um grande erro.

Porém, como qualquer coisa, apenas tome cuidado para estar sempre limpando a entrada do usuário, especialmente se estiver colocando a entrada do usuário na variável $_SESSION e, posteriormente, usando essa variável em uma consulta SQL.

Isso é algo bastante comum de se fazer, e a sessão geralmente será mais rápida do que ocorrências contínuas no banco de dados.Eles também são razoavelmente seguros, já que os desenvolvedores de PHP trabalharam duro para evitar o sequestro de sessão.

O único problema é que você precisa se lembrar de reconstruir a entrada da sessão quando algo mudar.E, se algo for alterado por um usuário que não seja o proprietário da sessão, o que resultaria na necessidade de atualizar essa chave, não haverá uma maneira fácil de notificar o sistema para atualizar essa chave de sessão.Possivelmente não é grande coisa, mas é algo que você deve estar ciente.

$_SESSION é muito útil em segurança, pois é uma forma do lado do servidor de armazenar informações enquanto um usuário está ativamente em suas páginas, portanto, é difícil de hackear, a menos que seu arquivo php ou servidor real tenha pontos fracos que sejam explorados.Uma implementação muito boa é armazenar uma variável para confirmar que o usuário está logado, e só permitir que ações sejam tomadas se ele estiver confirmado logado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top