Sessão PHP perdida após redirecionamento

132

Como resolver o problema de perder uma sessão após um redirecionamento em PHP?

Recentemente, encontrei um problema muito comum de perder a sessão após o redirecionamento. E depois de pesquisar neste site, ainda não encontro uma solução (embora isso tenha chegado mais perto).

Atualizar

Encontrei a resposta e pensei em publicá-la aqui para ajudar qualquer pessoa com o mesmo problema.

dayuloli
fonte
1
A questão é como resolver o problema de perder uma sessão após um redirecionamento no PHP. Eu já descobri a resposta, apenas postando aqui para que outras pessoas saibam. Porque minha solução não está no StackOverflow.
dayuloli
2
Tudo bem, mas este é um site de controle de qualidade. Faça sua pergunta uma pergunta.
Jeremy
Eu não percebi que era de você. Ainda assim, este site é para perguntas, não para respostas a perguntas que você já conhece.
21413 Aris
21
@ Aris Isso não é verdade, quando as pessoas têm uma pergunta sobre codificação, procuram o StackOverflow para obter ajuda. Se não houver respostas disponíveis, elas não poderão obter a ajuda de que precisam. Eu estou tentando fornecer essa resposta.
dayuloli

Respostas:

208

Primeiro, execute as verificações habituais:

  1. Certifique-se de que session_start();é chamado antes de qualquer sessão ser chamada. Portanto, uma aposta segura seria colocá-lo no início da sua página, imediatamente após a <?phpdeclaração de abertura antes de qualquer outra coisa. Verifique também se não há espaços em branco / guias antes da <?phpdeclaração de abertura .
  2. Após o headerredirecionamento, finalize o script atual usando exit();(Outros também sugeriram session_write_close();e session_regenerate_id(true), você pode experimentá-los também, mas eu usaria exit();)
  3. Verifique se os cookies estão ativados no navegador que você está usando para testá-lo.
  4. Verifique se register_globalsestá desativado, você pode verificar isso no php.iniarquivo e também usá-lo phpinfo(). Consulte isso para saber como desativá-lo.
  5. Verifique se você não excluiu ou esvaziou a sessão
  6. Certifique-se de que a chave na sua $_SESSIONmatriz superglobal não seja substituída em nenhum lugar
  7. Certifique-se de redirecionar para o mesmo domínio. Portanto, o redirecionamento de um www.yourdomain.compara yourdomain.comnão leva a sessão adiante.
  8. Verifique se a extensão do arquivo é .php(acontece!)

Agora, esses são os erros mais comuns, mas se eles não resolverem o problema, é mais provável que o problema esteja relacionado à sua empresa de hospedagem. Se tudo funcionar, localhostmas não no seu servidor remoto / de teste, provavelmente é o culpado. Portanto, verifique a base de conhecimento do seu provedor de hospedagem (tente também seus fóruns, etc.) Para empresas como FatCow e iPage, elas exigem que você especifique session_save_path. Então assim:

session_save_path('"your home directory path"/cgi-bin/tmp');
session_start();

(substitua "o caminho do diretório inicial" pelo caminho real do diretório inicial. Isso geralmente ocorre no painel de controle (ou equivalente), mas você também pode criar um test.phparquivo no diretório raiz e digitar:

<?php echo $_SERVER['SCRIPT_FILENAME']; ?>

O bit anterior a 'test.php' é o caminho do diretório inicial. E, claro, verifique se a pasta realmente existe dentro do diretório raiz. (Alguns programas não carregam pastas vazias ao sincronizar)

dayuloli
fonte
8
Muito bem escrito +1, se tudo falhar, basta usar cookies (gere uma string aleatoriamente e armazene-a no banco de dados e use-a como seu valor de cookie).
Dave Chen
2
alternar entre http en https também pode ser um problema stackoverflow.com/questions/441496/…
dev.e.loper
4
Note-se que a partir de php 5.4.0 register_globals foi removido, por isso já não causa um problema
anthonygore
2
Verifique também o log de erros do servidor da web; no meu caso, ocorreu um erro "Falha ao gravar dados da sessão (arquivos). Verifique se a configuração atual do session.save_path está correta". As permissões estavam erradas no diretório save_path.
timbonicus
Qualquer motivo para minhas sessões serem armazenadas em outro lugar que não seja session.save_path?
23715 Justin Justin
26

você deve usar "exit" após a chamada de cabeçalho

header('Location: http://www.example.com/?blabla=blubb');
exit;
KraftART Berlin
fonte
Existe um bug para o Gecko (por exemplo, Waterfox, Firefox, SeaMonkey), onde se houver qualquer saída de dados (por exemplo echo ' ';) ou espaço em branco de qualquer tipo, ele ignorará completamente o cabeçalho do local.
John
18

Eu tentei todas as soluções possíveis, mas nenhuma funcionou para mim! Claro, estou usando um serviço de hospedagem compartilhada.

No final, resolvi o problema usando 'url relativo' dentro do cabeçalho de redirecionamento!

header("location: http://example.com/index.php")

anulou os cookies da sessão

header("location: index.php")

funcionou como um encanto!

ali al-juanidi
fonte
7

Eu tive o mesmo problema. Eu trabalhei nele por várias horas e isso me deixou louco.

No meu caso, o problema foi chamado 404 devido a um favicon.ico ausente apenas no Chrome e Firefox. Os outros navegadores funcionaram bem.

Jeremie
fonte
Só queria agradecer por esta resposta, me fez perceber que 404 pedidos de imagens estavam sendo encaminhados pelo Varnish para PHP sem cookies e, portanto, novas sessões eram criadas constantemente. Pode nunca ter descoberto isso sem você.
Pascal Zajac
Eu tive o mesmo problema, meu favicon.ico estava sendo redirecionado (redirecionamento 302 do subdomínio para o domínio principal) e, portanto, gerava uma nova sessão sempre. Muito obrigado!
simdrouin
4

Quando eu uso o caminho relativo "dir / file.php" com a função header () no funciona para mim. Eu acho que a sessão não é salva por algum motivo quando você redireciona usando o URL completo ...

//Does retain the session info for some reason
header("Location: dir");

//Does not retain the session for some reason
header("Location: https://mywebz.com/dir")
user2999967
fonte
3

Isso me deixou perplexo por um longo tempo (e essa postagem foi ótima de encontrar!), Mas para quem ainda não consegue obter sessões entre redirecionamentos de página para funcionar ... eu tive que entrar no arquivo php.ini e ativar os cookies :

session.use_cookies = 1 

Eu pensei que as sessões funcionavam sem cookies ... na verdade, eu sei que elas deveriam ... mas isso resolveu meu problema pelo menos até que eu possa entender o que pode estar acontecendo no cenário geral.

sclarky
fonte
Eu não sabia que as sessões podem funcionar sem cookies! Aprenda algo novo todos os dias! programmerinterview.com/index.php/php-questions/…
dayuloli
é claro que eles PODEM funcionar sem cookies depende da sua configuração. Mas você deve saber o que faz. E tenha um bom motivo para fazê-lo. Porque é menos seguro. e caso você precise trabalhar por qualquer motivo sem cookies. Você deve pelo menos configurar ini_set ('session.use_strict_mode', '1'); e geralmente têm um tempo de sessão curto e, após o login do usuário, use session_regenerate_id (). Mas esteja avisado se algum usuário postar um link para um site em seu servidor em um fórum, as pessoas que clicarem nesse link assumirão a sessão. Talvez verificar o ip também seja uma boa ideia.
Michael
3

Eu tive um problema semelhante, embora meu contexto fosse um pouco diferente. Eu tinha uma configuração de desenvolvimento local em uma máquina cujo nome do host windowse endereço IP eram 192.168.56.2.

Eu poderia acessar o sistema usando um dos seguintes:

Após o login, meu código PHP seria redirecionado usando:

header('http://windows/');

Se o nome de domínio anterior usado para acessar o sistema não fosse windows, os dados da sessão seriam perdidos. Resolvi isso alterando o código para:

header('http://'.$_SERVER['HTTP_HOST'].'/');

Agora ele funciona independentemente do nome de domínio local ou endereço IP que o usuário coloca.

Espero que isso possa ser útil para alguém.

Stephen K. Karanja
fonte
3

Eu encontrei esse problema em uma página específica. Eu estava definindo os valores $ _SESSION em outras páginas antes de redirecionar e tudo estava funcionando bem. Mas esta página em particular não estava funcionando.

Finalmente, percebi que, nesta página em particular, estava destruindo a sessão no início da página, mas nunca a iniciando novamente. Então, minha função de destruição mudou de:

function sessionKill(){

    session_destroy();

}

para:

function sessionKill(){

    session_destroy();
    session_start();

}

E tudo funcionou!

NicB
fonte
3

Eu estava tendo o mesmo problema. De repente, ALGUMAS das minhas variáveis ​​de sessão não persistiram na página seguinte. O problema acabou sendo (no php7.1) o local do cabeçalho não deve ter WWW, ex https: // mysite . está ok, https: //www.mysite . perderá as variáveis ​​de sessão dessas páginas. Nem todas, apenas essa página.

Wynn
fonte
Isso porque www.mysite.comé visto como um domínio completamente diferente do que blog.mysite.comou simplesmentemysite.com
dayuloli
2

Estou lutando com isso há dias, verificando / tentando todas as soluções, mas meu problema era que não liguei session_start();novamente após o redirecionamento. Apenas assumi que a sessão ainda estava "viva".

Então não esqueça disso!

Jeffrey Roosendaal
fonte
Sim! este foi o meu problema também. Eu pensei que iniciar uma sessão de PHP era como acender uma luz para toda a casa. Não sabia que era preciso ativar o interruptor de cada quarto em que você entra.
Dale Thompson
1

Eu tive o mesmo problema e encontrei o caminho mais fácil. Eu simplesmente redirecionei para um redirecionamento .html com 1 linha de JS

<!DOCTYPE html>
<html>
<script type="text/javascript">
<!--
window.location = "admin_index.php";
//–>
</script>
</html>

em vez de PHP

header_remove();
header('Location: admin_login.php');
die;

Eu espero que isso ajude.

Love Gram

Gramrock
fonte
1

Se você estiver usando, session_set_cookie_params()talvez queira verificar se está passando o quarto parâmetro $securecomo true. Se estiver, é necessário acessar o URL usando https.

O $secureparâmetro sendo verdadeiro significa que a sessão está disponível apenas dentro de uma solicitação segura. Isso pode afetar você localmente mais do que nos ambientes de palco ou produção.

Mencionei isso porque passei a maior parte do dia tentando encontrar esse problema, e foi isso que resolveu para mim. Acabei de ser adicionado a este projeto e ninguém mencionou que era necessário https.

Portanto, você pode usar https localmente ou pode definir o $secureparâmetro como FALSEe usar http localmente. Apenas certifique-se de configurá-lo novamente para verdadeiro quando você fizer suas alterações.

Dependendo do seu servidor local, você pode ter que editar DocumentRootna httpd-ssl.confdo servidor para que o seu url local é servida https.

Andy Huggins
fonte
1

Outro motivo possível:

Esse é o meu espaço de armazenamento do servidor. O espaço em disco do meu servidor fica cheio. Então, removi alguns arquivos e pastas do meu servidor e tentei.

Foi trabalhado !!!

Estou salvando minha sessão no AWS Dynamo DB, mas ele ainda espera algum espaço no meu servidor para processar a sessão. Não sei por que !!!

Jayaprakash
fonte
1

Se você estiver usando o Laravel e tiver esse problema, será necessário salvar os dados da sessão antes de redirecionar.

session()->save();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit;
Aubrey Kodar
fonte
0

Eu também tive o mesmo problema com o redirecionamento não funcionando e tentei todas as soluções que encontrei, meu redirecionamento de cabeçalho estava sendo usado em um formulário.

Eu o resolvi colocando o redirecionamento de cabeçalho em uma página php diferente 'signin_action.php' e passando os parâmetros das variáveis ​​através dos parâmetros desejados nos URLs e reatribuindo-os no formulário 'signin_action.php'.

signin.php

if($stmt->num_rows>0) {
$_SESSION['username'] = $_POST['username'];
echo '<script>window.location.href = "http://'.$root.'/includes/functions/signin_action.php?username='.$_SESSION['username'].'";</script>';
error_reporting(E_ALL);

signin_action.php

<?php
require('../../config/init.php');
$_SESSION['username'] = $_GET['username'];
if ($_SESSION['username']) {

echo '<script>window.location.href = "http://'.$root.'/user/index.php";</script>';
exit();
} else {
echo 'Session not set';
}

?>

Não é uma solução alternativa bonita, mas funcionou.

Fluxo do empilhador
fonte
0

Para mim, o erro foi que tentei salvar um objeto não serializável na sessão para que uma exceção fosse lançada ao tentar gravar a sessão. Mas como todo o meu código de manipulação de erros já havia cessado qualquer operação, nunca vi o erro.

Eu poderia encontrá-lo nos logs de erro do Apache, no entanto.

Björn Tantau
fonte
0

Só para constar ... Eu tive esse problema e, depois de algumas horas tentando tudo, o problema era que o disco estava cheio e as sessões php não puderam ser gravadas no diretório tmp ... então, se você tiver esse problema, verifique se também...

iperich
fonte
Essa resposta funcionou para mim. Executamos uma Amazon Machine Image com nginx. Parece haver uma falha de que a pasta da sessão não pertence ao usuário correto (no nosso caso www), portanto, o desempenho chown -R www.wwwna pasta de sessões corrige o problema.
Joshua Joshua
0

Para mim, o Firefox armazenou o ID da sessão (PHPSESSID) em um cookie, mas o Google Chrome usou o parâmetro GET ou POST. Portanto, você só precisa garantir que o script de retorno (para mim: paypal checkout) confirme PHPSESSID no parâmetro url ou POST.

almisoft
fonte
0

Depois de tentar muitas soluções aqui no SO e em outros blogs ... o que funcionou para mim foi adicionar .htaccess à raiz do meu site.

RewriteEngine on
RewriteCond %{HTTP_HOST} ^yoursitename.com$
RewriteRule ^.*$ "http\:\/\/www\.yoursitename\.com" [R=301,L]
Vishal Kumar
fonte
0

Se você estiver usando o Wordpress, tive que adicionar este gancho e iniciar a sessão no init:

function register_my_session() {
    if (!session_id()) {
        session_start();
    }
}
add_action('init', 'register_my_session');
Jack
fonte
0

Nada funcionou para mim, mas descobri o que causou o problema (e o resolvi):

Verifique os cookies do navegador e verifique se não há cookies de sessão php em subdomínios diferentes (como um para " www.website.com " e outro para " website.com ").

Isso foi causado por um javascript que usou incorretamente o subdomínio para definir cookies e abrir páginas em iframes.

Julius S.
fonte
0

Primeiro, verifique se você está chamando session_start()antes de usar a $_SESSIONvariável.

Se você desativou o relatório de erros, tente ativar e ver o resultado.

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

Os motivos mais comuns que não são mencionados na resposta do @ dayuloli:

  1. Problema de espaço em disco. Verifique se o espaço em disco não está cheio. Você precisa de espaço para armazenar arquivos de sessão.

  2. O diretório da sessão pode não ser gravável. Você pode verificá-lo comis_writable(session_save_path())

F0G
fonte
0

Eu estava tendo o mesmo problema e fiquei louca procurando a resposta no meu código. Finalmente, achei minha hospedagem recentemente atualizada a versão PHP no meu servidor e não configurei corretamente o session_save_pathparâmetro no php.iniarquivo.

Portanto, se alguém ler isso, verifique a php.iniconfiguração antes de qualquer outra coisa.

Yova Turnes
fonte
0

Verifique se session_write_closenão é chamado entre session_start()e quando você define sua sessão.

session_start();

[...]

session_write_close();

[...]

$_SESSION['name']='Bob'; //<-- won't save
Jordan Daigle
fonte
0

Agora que o GDPR é uma coisa, as pessoas que visitam essa pergunta provavelmente usam um script de cookie. Bem, esse script causou o problema para mim. Aparentemente, o PHP usa um cookie chamado PHPSESSIDpara rastrear a sessão. Se esse script o excluir, você perderá seus dados.

Eu usei esse script de cookie . Tem uma opção para ativar cookies "essenciais". Eu adicionei PHPSESSIDà lista, o script parou de excluir o cookie e tudo começou a funcionar novamente.

Você provavelmente poderia habilitar algumas configurações do PHP para evitar o uso PHPSESSID, mas se o seu script de cookie for a causa do problema, por que não corrigi- lo ?

dodov
fonte
0

Corrigi esse problema após vários dias de depuração e era tudo porque meu URL de retorno do PayPal Express Checkout não tinha um 'www'. O Chrome reconheceu que os domínios deveriam ser tratados da mesma forma, mas outros navegadores às vezes não. Ao usar sessões / cookies e caminhos absolutos, não esqueça o 'www'!

miapuffia
fonte
0

Eu consertei, dando permissões de gravação em grupo para o caminho em que o PHP armazena arquivos de sessão. Você pode encontrar o caminho da sessão com a função session_save_path ().

franzisk
fonte
0

Hoje eu tive esse problema em um projeto e tive que alterar esse parâmetro para false (ou remover as linhas, por padrão, está desabilitado):

ini_set( 'session.cookie_secure', 1 );

Isso aconteceu porque o projeto real funciona sobre http e não apenas https. Encontrei mais informações nos documentos http://php.net/manual/en/session.security.ini.php

Oscar
fonte
0
ini_set('session.save_path',realpath(dirname($_SERVER['DOCUMENT_ROOT']) . '/../session'));
session_start();

Tarde demais para responder, mas isso funcionou para mim

Vipertecpro
fonte
0

Para mim, isso foi um erro de permissão e isso resolveu:

chown -R nginx: nginx / var / opt / remi / php73 / lib / php / sessão

Testei algumas horas em PHP e o último teste que fiz foi criar dois arquivos session1.php e session2.php.

session1.php:

session_start();

$_SESSION["user"] = 123;

header("Location: session2.php");

session2.php:

session_start();

print_r($_SESSION);

e estava imprimindo uma matriz vazia.

Neste ponto, eu pensei que poderia ser um problema de servidor e, de fato, era.

Espero que isso ajude alguém.

temo
fonte
1
O chown é uma solução MAU, pois será alterado novamente para o valor padrão na atualização do pacote. Veja os comentários na configuração padrão do pool (www.conf). Forma adequada se o uso outro diretório que o apache (ex: / var / lib / php / nginx / sessão)
Remi Collet
Você está certo. atualização do pacote foi a razão do meu problema em primeiro lugar. Mas já que foi dessa maneira, eu precisava de uma solução rápida que ajudasse. Meu administrador do SYS resolveu isso, não estou nem aí com o Linux.
temo