Ir para conteúdo

POWERED BY:

Arquivado

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

InterPlanet

[Resolvido] Sessao iniciada ou nao?

Recommended Posts

Ola a todos!

 

A situação:

 

Estou aprimorando a base dos meus sistemas desevolvidos para terceiros e resolvi isolar o login da sessao de forma que o sistema nao crie sessoes antes de validar o login e, em consequencia disto, nao criei arquivos de sessao desnecessarios, ate porque estas sao controladas pelo sistema com gravacao de entrada e da saida (botao logoff ou atraves da deteccao do fechamento do browser).

 

O problema:

 

Preciso validar se a sessao foi iniciada na pagina de login (que nao inicia a sessao, nao tem nela session_start() e afins) para poder redirecionar o usuario para a index do sistema e evitar que o mesmo logue novamente e assim criei uma nova sessao, o que acarretara deversos problemas ao controle das sessoes do sistema.

 

O codigo:

 

<?php Require('includes/sis/ini.carga.php'); SIS_Config('Teste');
##################################
# IPis - ©2000-2011              #
# http://www.ipis.com.br         #
# info@ipis.com.br               #
# Script by Fernando Lima        #
##################################

// REDIRECIONAMENTO para index caso ja esteja logado
If (isSet($_SESSION))
  { Header('Location: '.Geral_Base()); }

// VALIDACAO do POST
If ($_SERVER['REQUEST_METHOD'] === 'POST')
  { $Acao                   = SIS_LogIN($_POST);
    $Erro                   = empty($Acao['Erro']) ? '' : '('.$Acao['Erro'].') '.$Acao['Info']; }
?>

<-- HTML ... -->

 

Como podem ver, pus onde preciso redirecionar um codigo [ isSet($_SESSION) ] que sei que nao funfa, pois nao ha sessao, dã! :) E so pra mostrar o que pretendo fazer.

 

E ai? Como validar se a sessao existe sem ter iniciado a mesma? E Possivel?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Criando seu próprio handler de sessão você consegue fazer isso.

 

Não que você vá, de fato abolir session_start(), afinal, sem ela você não tem acesso às informações de sessão.

 

Eu aprendi que, já que só pode haver uma inicialização de sessão, uma classe que manipule tudo referente a ela, deve seguir o padrão Singleton.

 

Porém você vai mudar ligeiramente a forma como você obtém a instância do objeto.

 

A idéia seria você ter nessa classe um método estático start(), ao invés do comumente usado getInstance(), que:

 

  • Define a instância do objeto da classe à uma propriedade se a sessão não tiver sido inicializada (ver abaixo) ao invés de o objeto não ter sido criado ainda.
  • Inicia a sessão, atribuindo o session_start() à uma variável e, caso esse retorno seja positivo você você seta como TRUE outr a propriedade estática. Eu chamo a minha de $sessionStarted.
  • Gera um ID de sessão se não houver um ainda. Para isso obtenha o ID através de session_id() e, se este estiver vazio, gere outro.

O restante da classe de abranger as demais tarefas que um handler de Sessão deve ter:

 

  • Gravar os dados de sessão, usando session_write_close()
  • Gerar o ID usado acima pode estar num método à parte também, permitindo que se altere sempre que necessário. Essa... não sei se regeneração cabe no contexto da frase, mas seria isso... do ID, você faz com session_regenerate_id()
  • Destruir a sessão, através de session_destroy() com opção de remover o cookie.
  • Se for permitir remover o cookie dito acima, num métod à parte você executa as rotinas necessárias para removê-lo. O cookie logicamente se encontra em $_COOKIES e o índice a ser buscado é retornado por session_name().

E alguns accessors:

 

  • Método para verificar se a sessão foi iniciada, buscando o valor da propriedade setada como TRUE em start()
  • Método para verificar se a sessão foi destruída, para não usá-la sem dever.
  • Método para verificar se a sessão existe
  • Método wrapper para obter o ID de sessão atual

E por aí vai, com tantos métodos e rotinas quantas forem necessárias para que você tenha facilidade e flexibilidade totais no manipulamento de Sessões...

 

É trabalhoso? De fato é. No meu caso é o segundo maior arquivo do sistema (só perde para a View).

 

Porém com isso eu NUNCA mais vi o infame erro de que a sessão já foi inicializada, já eu mesmo disparo uma exceção se tal circuntância ocorrer.

 

Tenho flexibilidade total para usar o handler de sessão que eu quiser para tarefa que eu quiser: o nativo (arquivo), MongoDB, Memcache, MySQL...

 

Vale a pena :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Bruno! Isto é uma maravilha!

Eu realmente preciso conhecer isto. Ja comecei a pesquisar!

Contudo tendo em vista a minha necessidade atual, creio nao ser o mais adequado pois é muito codigo a mais, mais uma classe e etc...

 

Preciso de algo mais objetivo. Estava pensando aqui: poderia criar um cookie ao iniciar a sessao e checar na pagina de login, MAS, como todos sabemos, fico limitado ao usuario ter o recurso habilitado no navegador. :(

 

Alguma outra sugestao/possibilidade?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então, não conheço não. Mas assim, falei mais pra assustar ^_^

 

Não é assim tão complicado. Pra mim a parte mais complicada foi a outra metade, a que me permite usar o handler que quiser. A parte da manipulação de sessão foi até bem fácil.

 

Se você sabe o que é Singleton, é só adaptar o mini passo a passo acima.

 

Se não, faça uma busca e aprenda o que é e quando usar, implemente uma classe Singleton padrão e altere-a aos poucos.

 

De repente, você monta ela em algumas horinhas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então, não conheço não. Mas assim, falei mais pra assustar ^_^

 

Não é assim tão complicado. Pra mim a parte mais complicada foi a outra metade, a que me permite usar o handler que quiser. A parte da manipulação de sessão foi até bem fácil.

 

Se você sabe o que é Singleton, é só adaptar o mini passo a passo acima.

 

Se não, faça uma busca e aprenda o que é e quando usar, implemente uma classe Singleton padrão e altere-a aos poucos.

 

De repente, você monta ela em algumas horinhas.

 

Huahuuhahua! beleza!

 

Singleton, é um padrão de projeto de software (do inglês Design Pattern). Este padrão garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto.

 

Fonte aos demais interessados.

 

So isso ja me deixou curiosissimo e tenha certeza que sua dica sera aproveitada! Muito bom.

 

Todavia, reitero, preciso no momento de algo mais "simples"! A busca continua... :joia:

 

------------------------

Edição:

 

Pessoal?

Seria possivel usar uma var global?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Singleton não e tão dificil .. so tem a propia instancia embutida na classe ..

isso que faz uma class Singleton :lol:

 

<?php
class SingletonClass
{
       private static $instance;
       private function __construct() { } // Evita que a classe seja instanciada publicamente
       private function __clone() { } // Evita que a classe seja clonada
       public static function getInstance()
       {
               if (!isset(self::$instance)) { // Testa se há instância definifa na propriedade
                       self::$instance = new self; // o new self cria uma instância da própria classe
               }
               return self::$instance;
       }
}

 

E uma simples dica , não se acostume a trabalhar com esse Header de Redirecionamento .. imprima um http equiv

If (isSet($_SESSION))
  { Header('Location: '.Geral_Base()); } // -> troque por , echo '<meta http-equiv="refresh" content="0;'.Geral_Base().'">';

 

A Ideia do bruno e bem Legal , vou ate testar depois .. se o singleton retorna a instancia da propia classe , você pode fazer ele retornar a sessão :lol:

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

E uma simples dica , não se acostume a trabalhar com esse Header de Redirecionamento .. imprima um http equiv

If (isSet($_SESSION))
  { Header('Location: '.Geral_Base()); } // -> troque por , echo '<meta http-equiv="refresh" content="0;'.Geral_Base().'">';

 

Porque trocar? tem algum problema em relação a segurança?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Kratos Zohr , não , mais esse Header as vezes da problema ..( não e o caso )

fala que ja foi enviado por outra pagina o http equiv faz a mesma coisa :huh:

 

Hummm! Que tipo de problema? E em que circunstancia, da um exemplo.

 

E pra nao fugir do assunto, ninguem tem outra ideia/possibilidade/sugestao?

Nao quero usar a classe so nesta parte do sistema.

 

Com globals nao da certo, tentei aqui.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara não e nenhum problema Inevitavel não , e porque as vezes você tem 2 Headers em uma pagina ..

Ai se você já enviou um Header em cima .. o de baixo vai da pal .. vai dar erro "Headers Alerady Send By .. on line .."

 

Da uma olhada , pode te servir pra alguma coisa :lol:

:seta: http://code.imasters.com.br/index.php?/topic/210-sessoes-e-cookies/

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara não e nenhum problema Inevitavel não , e porque as vezes você tem 2 Headers em uma pagina ..

Ai se você já enviou um Header em cima .. o de baixo vai da pal .. vai dar erro "Headers Alerady Send By .. on line .."

 

Da uma olhada , pode te servir pra alguma coisa :lol:

:seta: http://code.imasters.com.br/index.php?/topic/210-sessoes-e-cookies/

 

Ha ta! B)

 

Quanto a dica, seque o padrao supracitado. Mesmo assim, obrigado @Andrey.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara não e nenhum problema Inevitavel não , e porque as vezes você tem 2 Headers em uma pagina ..

Ai se você já enviou um Header em cima .. o de baixo vai da pal .. vai dar erro "Headers Alerady Send By .. on line .."

 

hehehehe, mas isso é problema do programador e não do cabeçalho HTTP.

 

De fato, o correto é utilizar o cabeçalho HTTP e não um POG para contornar uma falha de projeto.

 

Quanto a dica, seque o padrao supracitado. Mesmo assim, obrigado @Andrey.

 

Quando a dica do Bruno, aqui segue um exemplo: http://forum.imasters.com.br/topic/407092-sessoes-php-com-nosql/

 

Para verificar se uma sessão foi inicializada, você pode verificar o session_id()

 

<?php
$sid = session_id();

if ( empty( $sid ) ) {
echo 'A sessão não foi inicializada';
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

No meu caso, quando não tenho um ID de sessão, eu gero outro ao invés de mostrar uma mensagem, via exceção ou não.

 

Eu nunca havia tido necessidade de uma classe desse tipo, mas quando tive esse problema, o Matias me sugeriu usar um helper do Zend Framework que trabalhava co sessões.

 

Como eu queria algo elegante, sem ter de espalhar os $_SESSION pelo código montei a classe.

 

Algumas semanas depois disso, apareceu publicamente essa do João, junto com o frenesi do NoSQL (que até então eu deconhecia). Daí fiz uma pequena (porém trabalhosa) adaptação para poder flexibilizar os handlers.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para verificar se uma sessão foi inicializada, você pode verificar o session_id()

 

<?php
$sid = session_id();

if ( empty( $sid ) ) {
echo 'A sessão não foi inicializada';
}

 

@Joao,

 

Na minha pagina de login (que nao inicia a sessao), uma chamada a session_id() irá retornar o id da sessao se o usuario ja tiver logado e, consequentemente iniciado a sessao?

 

Testando... Ja to louco com isso, ja tentei tantas coisas... Que pena que os cookies podem ser desabilitados...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Na minha pagina de login (que nao inicia a sessao), uma chamada a session_id() irá retornar o id da sessao se o usuario ja tiver logado e, consequentemente iniciado a sessao?

 

Se session_id() retornar alguma coisa, significa que uma sessão foi iniciada, caso contrário, significa que nenhuma sessão foi iniciada.

 

Na prática, se a única forma de ter uma sessão é o usuário ter feito login, então sim, se session_id() retornar o id da sessão, o usuário já terá efetuado o login.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Na minha pagina de login (que nao inicia a sessao), uma chamada a session_id() irá retornar o id da sessao se o usuario ja tiver logado e, consequentemente iniciado a sessao?

 

Se session_id() retornar alguma coisa, significa que uma sessão foi iniciada, caso contrário, significa que nenhuma sessão foi iniciada.

 

Na prática, se a única forma de ter uma sessão é o usuário ter feito login, então sim, se session_id() retornar o id da sessão, o usuário já terá efetuado o login.

 

Vou reformular minha pergunta de maneira mais objetiva levando em consideração o fato de a sessao ja ter sido criada na index.php (usuario ja logado), ou seja, a sessao existe.

 

Na login.php, "sem iniciar a sessao", session_id() deve retornar o id da sessao criada anteriormente noutra pagina?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Por quê você não testa?

 

index.php

<?php

session_start();

printf( 'Current Session ID: %s', session_id() );

print '<br /><br /><a href="index2.php">Next Page</a>';

index2.php

<?php

print 'Current Session ID:<br /><br />';

var_dump( session_id() );

O correto seria o segundo código disparar um E_WARNING, já que está se usando uma função de sessão, sem ter uma sessão ativa. Mas de repente esqueceram de colocar isso ^_^

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ok @Bruno!

Em suma, nao funciona! Obrigado mesmo a todos pela ajuda e pelos comentarios.

Ja que nao e possivel detectar a sessao nao ha iniciando entao terei de continuar a usar a sessao no login.

Vou estudar uma forma de separar as sessoes com identificacao e excluir as que nao passaram do login usando o banco de dados e detectando o fechamento do navegador na tela de login, como ja e feito na index.

 

Mais uma vez, obrigado a todos.

Abraç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.