Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

nakid.mkt

Encerrar Session ao fechar a aba ou o browser

Recommended Posts

Boa Tarde Pessoal.

 

Desenvolvi um site de comunidade virtual como orkut e cia, e está na fase de testes.

 

O sistema de login foi feito com sessions.

 

Quando os usuários logados fecham o browser sem clicar em "sair" (o que a maioria faz) pode acontecer 3 coisas quando o usuário acessa novamente meu site:

 

1 - A Session foi expirada e o usuário tem que fazer login novamente; (OK)

2 - A Session continua ativa e o usuário pode navegar normalmente como se continuasse no site desde o último login (OK)

3 - O usuário continua logado mas com erros graves. (NÃÃÃO!!!)

 

 

Gostaria que quando o usuário fechase o browser ou a aba sem clicar em sair, a session expirasse como se tivesse clicado em "sair" (session_destroy())

 

Alguma luz?

 

 

////////////////// ERRO QUE OCORRE NO CASO 3 CITADO ACIMA, pra quem estiver curioso

 

 

quando o usuário faz login, abro essas informações:

 

$_SESSION["USU_ID"]   = 999;
$_SESSION["USU_NICK"] = 'nonono';
$_SESSION["USU_FOTO"] = 'nonono.jpg'
$_SESSION["USU_CIDADE"] = 'nonono dos campos'
$_SESSION["USU_ESTADO"] = 'NO';
$_SESSION["USU_SEXO"] = 'N';

 

quando o usuario acessa o site sem ter clicado em "sair" da última vez, pode acontecer da sessão continuar aberta mas com apenas a informação $_SESSION["USU_ID"];

 

as informações $_SESSION["USU_NICK"] , $_SESSION["USU_FOTO"] e todas as outras entram vazias.

 

Mas até ai até que tudo bem, uma vez que este usuário só não conseguirá ver a foto no seu perfil, o nick, etc... Mas se ele enviar uma mensagem pra outro usuário vai gravar tudo direitinho no BD.

 

O erro pior mesmo é que já aconteceu de: além de abrir apenas o $_SESSION["USU_ID"], abre com o ID errado. 2 vezes uma amiga minha que tem o perfil

de Fernanda, ao abrir essa "Sessão fantasma", enviou uma mensagem e apaceceu como Gustavo. Um outro usuário com outro ID. E o Gustavo nunca usa o computador dela.

 

 

Então quero encerrar a sessão toda vez! É mais seguro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Coloca um onbeforeunload em todas as páginas que desejar que isso aconteca,nesse onbeforeunload você faz uma chamada assincronica a um de seus scripts server-side onde neles você da uma session_start(),session_unset() e session_destroy().

Ilustrando:

<html>
	<head>
		<title>Exemplo</title>
		<script>
			var ajax;
			function initAjax(){
				var ajax;
				try {
					ajax = new XMLHttpRequest();
				} catch(err){
					try {
						ajax = new ActiveXObject("Microsoft.XMLHTTP');
					} catch(err){
						try {
							ajax = new ActiveXObject("Msxml2.XMLHTTP");
						} catch(ferr){
							alert("Script não rodará como deveria");
						}
					}
				}
				return ajax;
			}
			function fechaSess(){
				ajax = initAjax();
				if(ajax){
					//Burocracia já que o response não nos importa
					ajax.onreadystatechange = function(){
						if(ajax.readyState == 4){
							if(ajax.status == 200){
								alert(ajax.responseText);
							}
						}
					}
					ajax.open("POST", "fechasess.php", true);
					//Burocracia,já que enviamos null
					ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
					ajax.send(null);
				}
			}
		</script>
		<noscript>
			<font color="#ff0000" size="20px">Favor ativar o javascript</font>
		</noscript>
	</head>
	<body onBeforeUnload="java script:fechaSess();">
		Site ------
	</body>
	</body>
</html>

fechasess.php:

<?php
session_start();
session_unset();
session_destroy();
echo 'Sessão fechada';
?>

Em java,não tem as diretivas que definem isso (como no php),então,em java sempre fiz 'coisas assim' (fazendo gambiarras).

Voltar,avançar,fechar a página são considerados pelo onbeforeunload,o que faz a coisa incomoda.Se estiver usando uma index,e nela incluir os arquivos,o problema não é tanto,já que apenas 'um body' tem esse evento associado a ele (continua meio incomodo,porem mais comodo).

Dá também uma olhada nas diretivas do php.ini (no seu caso...acho que não ajuda...),lá tem uma que define o que voce quer.

Abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá proust!

 

Obrigado pela resposta.

 

 

Como o usuário logado pode fechar o browser em qualquer página, eu teria que colocar o <body onBeforeUnload="java script:fechaSess();"> en todas as páginas

 

 

Isso funcionaria perfeito se o onBeforeUnload pegasse apenas o fechamento de aba ou browser, e mudanças de url pra fora do meu sistema.

 

O problema é que qualquer link que o usuário clicar pra navegar dentro do site, o onBeforeUnload="java script:fechaSess();" vai deslogar o cara.

 

Estive pensando numa forma de usar o $_SERVER['SERVER_NAME'] dentro do arquivo fechasess.php pra ver pra onde o cara ta indo, mas não to conseguindo imaginar como. Mesmo porque o Script fechaSess(); e consequentemente o fechasess.php é executado enquanto a página ainda não alterou. Assim não consigo saber se o cara ta indo pra uma página fora do meu sistema, navegando dentro do sistema ou fechando o browser.

 

 

Acho que é isso mesmo, não é? Ou eu falei besteira?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se tiver só a index...e você usar dom ou includes,o incomodo é menor,porém ainda continuam os problemas.

Rodando de um webserver,tais incomodos podem (ou não) ser resolvidos pegando o document.referrer.

No unload do body,você chama aquela função,na função você checa o referrer,se apontar para uma página no servidor,não faz nada,se for null/undefined ou apontar para uma página fora,acaba com a sessão.

function fechaSess(){
				if(document.referrer != undefined && document.referrer != ''){
					ajax = initAjax();
					if(ajax){
						//Burocracia já que o response não nos importa
						ajax.onreadystatechange = function(){
							if(ajax.readyState == 4){
								if(ajax.status == 200){
									alert(ajax.responseText);
								}
							}
						}
						ajax.open("POST", "fechasess.php", true);
						//Burocracia,já que enviamos null
						ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
						ajax.send(null);
					}
				}
			}

Não é totalmente funcional.

Abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

proust, obrigado pelas dicas, mas que o document.referrer indica de onde o usuário veio, e não pra onde ele vai.

 

 

 

Aliás, nem sei se da pra detectar isso.

 

 

Mas muito obrigado mesmo. Foram excelentes idéias que me passou.

 

 

O negócio vai ser estudar um sistema de login mais seguro que simplismente abrir e fechar sessions

 

Vou dar uma estudada nisso que achei aqui

 

http://forum.imasters.com.br/index.php...&hl=session

 

 

Vai me tomar um tempo que eu não tenho... mas acho que vai ter que ser assim

 

 

Abração

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, tava tendo esse problema, procurei no google e nada... dai juntei algumas ideias e mais meus metodos POG (Programação Orientada a Gambiarras) e conseguir fazer de uma forma que resolveu meu problema e aposto que conseguiria resolver o seu...

 

na verdade peguei a ideia mais comum na internet do onunload no body de todas as páginas, chamando a função fechasess('fechar') que esta por sua vez vai chamar a página que contem o comando de finalizar sessão.

 

o grande segredo mora justamente no fato de que o onunload pega qualquer coisa que faça sair da página seja isso um link, volta de historio, ou qualquer outra coisa.

 

então o que eu fiz foi adicionar a esta função, também a função de redirecionar página e passo todos os meus links por essa função:

 

por exemplo <a href="fechasess('admin.php')">Admin</a>

 

minha função fechasess() possui um verificador e vai detectar qual foi a informação enviada para esta função caso seja um link como o que eu falei ele vai retornar o admin.php e vai verificar se eh diferente do meu parametro do unload que é o "fechar" como é diferente ele vai setar minha variavel check pra 1 e redirecionar, no que a página é redirecionada a função unload vai entrar com o parametro "fechar" porém a função vai verificar a variavel check, e ela vai estar como 1 por ter vindo de um link, dai ela não vai fechar a seção. no caso do usuário simplesmente fechar o brower no x ou sair de qualquer outra forma o unload vai entrar com o parametro fechar logo de gara fazendo assim a variavel check continuar com o valor indefinido e por tanto ela vai passar no check e chamar a página de logout.

 

 

Adicione em todas as páginas

 

<script>

var check;

function fechasess(url) {

if (url == 'fechar'){

if (check != 1) { window.location=("logout.php"); }

}else{

check = 1;

window.location=(url);

}

}

</script>

<body onunload="java script: fechasess('fechar');">

 

para criar seus links utilize essa função como redirecionamento:

 

<a href="fechasess('fotos.php')">Fotos</a>

<input type=button value="Fotos" onclick="fechasess('fotos.php')">

 

caso seja um formulário de POST você pode acrescentar algo tipo:

 

<form method="post" action="editar.php" onsubmit="fechasess('editar.php')" target="_self">

 

se você usa uma função java para abrir uma página com informações de get tipo window.location=("exibir.php?nome="+nome);

 

é só substituir o window.location= para fecharsess:

 

fecharsess("exibir.php?nome="+nome);

 

na logout.php coloque:

 

e mais qualquer outra rotina que você queira fazer quando a pessoa sair da página

 

<?php

session_start();

session_destroy();

?>

 

o unico incoveniente desse metódo é que se a pessoa pressionar f5 ela será deslogada... eu consegui até fazer uma função pra detectar o f5 porém ele é confundido com o 't' dai caso a pessoa apertasse t iria atualizar também... mas caso você utilize e descubra uma forma de distinguir o f5 do t me avisa .... espero ter ajudado

 

OBS.: fiz isso agora... não pude testar em todos os browsers...

Compartilhar este post


Link para o post
Compartilhar em outros sites

então cara como eu tinha dito tinha acabado de fazer a função e não tinha testado ainda, dai fui testar no Google Chrome e já tive um probleminha, porém consegui resolver ficando assim:

 

<script>

var check;

function fechasess(url) {

if (url == 'fechar'){

if (check != 1) { window.location=("logout.php"); alert('Sua sessão foi finalizada.');}

}else{

check = 1;

window.location=(url);

}

}

</script>

<body onunload="fechasess('fechar')">

 

na verdade a unica coisa que fiz foi adicionar o alert informando que a sessão foi finalizada. Não sei porque no google chrome ele não realizava o window.location=("logout.php"); acho que ele encerra o aplicativo antes que o browser possa carregar completamente a logout.php, dai no que eu inseri esse alert ele funciona normalmente... tanto no IE quanto no Chrome e ainda informa ao usuário que a sessão dele foi terminada :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

então... consegui fazer ele detectar o F5... o unico problema é que o script não funciona nem no Safari nem no Opera pra detectar o onunload... no safari até detecta mas ele não chama a página de logout... consegui também tirar o alert do Google Chrome e do FF, usando em conjunto com o onunload a onbeforeunload... saca só...

 

<script>

var check;

function fechasess(url,e) {

 

if (url == 'f5') { //Entra quando uma tecla é apertada

 

if (e.keyCode == 116) { check = 1; } //Verifica se a tecla é F5 no IE, se for bloqueia o logout

 

if (e.which == 116) { check = 1; } //Verifica se a tecla é F5 no FF, se for bloqueia o logout

 

}else if (url == 'logout.php') { //Entra quando o onunload ativa

 

if (check != 1) { document.location=(url); } //Verifica se deve ativar o logout ou não

}else{ //Entra quando for um link

check = 1; //Bloqueia o logout

 

document.location=(url); //Redireciona o link

}

}

</script>

<body onkeydown="fechasess('f5',event)" onkeypress="fechasess('f5',event)" onbeforeunload="fechasess('logout.php')" onunload="fechasess('logout.php')">

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa Tarde Pessoal.

 

Desenvolvi um site de comunidade virtual como orkut e cia, e está na fase de testes.

 

O sistema de login foi feito com sessions.

 

Quando os usuários logados fecham o browser sem clicar em "sair" (o que a maioria faz) pode acontecer 3 coisas quando o usuário acessa novamente meu site:

 

1 - A Session foi expirada e o usuário tem que fazer login novamente; (OK)

2 - A Session continua ativa e o usuário pode navegar normalmente como se continuasse no site desde o último login (OK)

3 - O usuário continua logado mas com erros graves. (NÃÃÃO!!!)

 

 

Gostaria que quando o usuário fechase o browser ou a aba sem clicar em sair, a session expirasse como se tivesse clicado em "sair" (session_destroy())

 

Alguma luz?

 

 

////////////////// ERRO QUE OCORRE NO CASO 3 CITADO ACIMA, pra quem estiver curioso

 

 

quando o usuário faz login, abro essas informações:

 

$_SESSION["USU_ID"]   = 999;
$_SESSION["USU_NICK"] = 'nonono';
$_SESSION["USU_FOTO"] = 'nonono.jpg'
$_SESSION["USU_CIDADE"] = 'nonono dos campos'
$_SESSION["USU_ESTADO"] = 'NO';
$_SESSION["USU_---O"] = 'N';

quando o usuario acessa o site sem ter clicado em "sair" da última vez, pode acontecer da sessão continuar aberta mas com apenas a informação $_SESSION["USU_ID"];

 

as informações $_SESSION["USU_NICK"] , $_SESSION["USU_FOTO"] e todas as outras entram vazias.

 

Mas até ai até que tudo bem, uma vez que este usuário só não conseguirá ver a foto no seu perfil, o nick, etc... Mas se ele enviar uma mensagem pra outro usuário vai gravar tudo direitinho no BD.

 

O erro pior mesmo é que já aconteceu de: além de abrir apenas o $_SESSION["USU_ID"], abre com o ID errado. 2 vezes uma amiga minha que tem o perfil

de Fernanda, ao abrir essa "Sessão fantasma", enviou uma mensagem e apaceceu como Gustavo. Um outro usuário com outro ID. E o Gustavo nunca usa o computador dela.

 

 

Então quero encerrar a sessão toda vez! É mais seguro.

 

facil rapaz :)

na pagina inicial do teu site antes do codigo da pagina pões:

?php session_start(); ?>

 

unset($_SESSION['USU_ID']);

 

E PRONTO: NÃO É PRECISO FAZERES O LOGOUT, BASTA SAIR DA ABA...OU PAGINA...OU FECHAR O BROWSER.... QUE A COISA FICA RESOLVIDA, NAO CONSEGUES LA IR SEM INICIAR OUTRA VEZ A SESSÃO!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.