O Chrome está criando sessões duplicadas com o mesmo id.

Eu encontrei um problema enquanto eu estava revisando minha biblioteca de session hoje, e esta pode ser a primeira vez que eu já vi um problema específico do navegador em um script de back-end. Espero que alguém possa esclarecer.

Basicamente, como funciona a biblioteca de session é: quando instanciado, ele verifica se há um cookie chamado ‘id’ (na forma de um resultado uniqid) na máquina do cliente. Se um cookie for encontrado, o script verificará isso e uma cópia hash da string do agente do usuário em relação às inputs em uma tabela de session. Se uma input correspondente for encontrada, o script retomará a session. Se nenhum cookie chamado ‘id’ for encontrado, ou se nenhuma input correspondente existir na tabela de sessões, o script cria ambos. Bastante padrão, penso.

Agora, aqui é a parte estranha: no Firefox, tudo funciona como previsto. O usuário recebe uma session, que ele sempre retomará após a conexão, enquanto 24 horas de inatividade não tiverem decorrido. Mas quando eu visitar a página no Chrome, mesmo que pareça o mesmo e parece estar executando consultas na mesma ordem, vejo duas inputs na tabela de session. As sessões compartilham uma string de agente, mas as ids são diferentes e os logs do timestamp indicam que a session de fantasmas está sendo criada em breve (dentro de um segundo) após a criação do usuário.

Para fins de debugging, estive a imprimir consultas na canvas à medida que foram executadas, e este é um exemplo do que estou vendo quando o Chrome deveria abrir uma session e, de alguma forma, abrir duas em vez disso:

// Attempting to resume a session SELECT id FROM sessions WHERE id = '4fd24a5cd8df12.62439982' AND agent = '9bcd5c6aac911f8bcd938a9563bc4eca' // No result, so it creates a new one INSERT INTO sessions (id, agent, start, last) VALUES ('4fd24ef0347f26.72354606', '9bcd5c6aac911f8bcd938a9563bc4eca', '1339182832', '1339182832') // Clear old sessions DELETE FROM sessions WHERE last < 1339096432 

E aqui está o que eu vejo no database depois:

 id, agent, start, last 4fd24ef0347f26.72354606, 9bcd5c6aac911f8bcd938a9563bc4eca, 1339182832, 1339182832 4fd24ef0857f94.72251285, 9bcd5c6aac911f8bcd938a9563bc4eca, 1339182833, 1339182833 

Estou faltando alguma coisa óbvia? O único que posso pensar é que o Chrome pode estar criando uma session oculta em segundo plano, possivelmente para rastrear a página. Se for esse o caso, pode se tornar um problema mais tarde, quando eu começar a associar sessões ativas com inputs na tabela de usuários. Procurei possíveis erros no meu script, mas não encontrei nada até agora, e tudo funciona conforme o esperado no Firefox.

Já enfrentei isso antes e estava igualmente confuso. Desde há alguns meses, o Chrome tem pré-habilitação ativada. Assim, para acelerar a velocidade percebida para os usuários, ele rastreia a maioria dos links na página e recupera e os processa parcialmente com antecedência. Ótimo para os usuários finais, pois, se você estiver na banda larga, pode realmente reduzir os tempos de mudança de página.

Infelizmente para nós desenvolvedores web, isso leva a confusão como a acima. Isso acontece, por exemplo, quando um usuário do Chrome visita um site e ainda não foi atribuído um cookie ou uma session, mas o navegador pregou várias páginas e foi atribuído várias sessões.

Então, digamos que alguém visita uma página com links para diferentes áreas do seu script PHP e o script foi projetado para atribuir um cookie a todos os visitantes … se o Chrome buscar duas dessas páginas simultaneamente ou perto dela, o PHP acabará atribuindo diferentes sessões porque outro thread no Chrome exigirá basicamente uma nova session / cookie antes que a outra tarefa seja concluída.

Existem duas soluções que conheço: uma é a API de JavaScript do Google para lidar com o prerendering , que não encontrei particularmente bom. A outra maneira é executar uma verificação mais rigorosa ao distribuir sessões e cookies do PHP. Ou não atribuir sessões a usuários convidados, ou adicionar algumas verificações adicionais (IP, nome do host, seja o que for).

Espero que ajude.