Jump to content
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.

Share this post


Link to post
Share on other 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!

Share this post


Link to post
Share on other 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?

Share this post


Link to post
Share on other 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!

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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...

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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')">

Share this post


Link to post
Share on other 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!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.