Avançar para a área de conteúdo

ir para o conteúdo principal

developerWorks Brasil  >  Software livre  >

Crie Web sites rapidamente com CakePHP, Parte 4: Use os componentes de Sessão e de Manipulador de Solicitação do CakePHP

Agilize os aplicativos PHP

developerWorks
Ir para a página anteriorPágina 3 de 9 Ir para a próxima página

Opções de documento

Código de amostra


Classificar este tutorial

Ajude-nos a melhorar este conteúdo


Manuseio de sessão

Quando é feita uma solicitação ao Web site, ela é totalmente independente de toda outra solicitação antes dela. Para implementar a funcionalidade de usuário, determinado cliente Web precisa de acesso repetido a uma informação única, possivelmente secreta. Isso é chamado manuseio de sessão em aplicativos Web, e as sutilezas de manusear sessões de forma adequada são uma dor de cabeça para muitos desenvolvedores.

Noções básicas de manuseio de sessão

A ideia básica é a mesma em qualquer linguagem de programação. Após visitar o Web site pela primeira vez, o cliente recebe uma identificação única, em geral armazenada como cookie. No lado do servidor, é armazenado uma matriz de variáveis, de algum modo, que corresponde àquela identificação única. Em qualquer solicitação posterior do mesmo cliente, a identificação única é enviada junto com a solicitação, e o servidor carrega o array na memória. Essas variáveis são chamadas de variáveis de sessão para o cliente. Em PHP, elas são armazenadas em uma $_SESSION variável global.

Você poderia simplesmente usar a variável global $_SESSION para acessar informações da sessão ao usar o CakePHP. Contudo, o CakePHP tem seu próprio objeto de manuseio de sessão, que, como veremos depois, tem vários benefícios.



Voltar para parte superior


Manuseio de sessão dentro do Tor

Já implementamos sessões sem muito esforço. Quando o usuário faz o login, o objeto UsersController armazena o nome de usuário e o associa automaticamente ao cliente durante solicitações posteriores.

Cada objeto Controller (qualquer coisa herdada de AppController) tem acesso automaticamente ao componente de Sessão. Lembre-se de que Component é uma classe associada ao controlador que permite funcionalidade extra, de forma bem parecida a um auxiliar que fornece funcionalidade extra a uma visualização. Você usou o componente Acl na Parte 2 quando acrescentou ACLs. Lembre-se de que você precisa acrescentar a linha a seguir no início das classes ProductsController e UsersController: var $components = array('Acl');.

Embora o manuseio de sessão seja um componente do CakePHP, é um componente padrão incluído com cada controlador, de modo que não é necessário acrescentá-lo a essa lista.

Para usar o componente de Sessão, simplesmente acesse a variável de instância de sessão do controlador. As duas funções mais importantes do manipulador de sessão são a configuração e obtenção de variáveis, que são obtidos pela chamada dos métodos read e write. No caso de login de usuário, você usou o código da Listagem 7 para gravar o nome de usuário do cliente atual na sessão. Esse código se localiza na classe UsersController.


Listagem 7. Usando o método write para armazenar o nome de usuário
                    
function login()
{
  ...

  $this->Session->write('user', $this->data['User']['username']);

  ...
{
                

O método write usa dois parâmetros. O primeiro é a chave atribuída e o segundo, o valor para atribuir a ele. Neste caso, a chave é user e o valor é o nome de usuário inserido (veja a Listagem 8). O nome de usuário é acessado depois para testar se o produto pode ser visto ou editado com base na ACL.


Listagem 8. Usando o método read para acessar o nome de usuário
                    
function view($id) {
  ...

  if ($this->Acl->check($this->Session->read('user'), 
$id.'-'.$product['Product']['title'], 'read'))
  {
    ...
  }
}
                

O método read usa um único parâmetro — a chave que você deseja acessar — e retorna o valor que foi armazenado.



Voltar para parte superior


Armazenando sessões

Nada disso deve ser novo para desenvolvedores Web, mas o manuseio de sessão em geral é um assunto simples para aplicativos pequenos. Se um aplicativo exige que informações sensíveis do usuário sejam armazenadas na sessão, como senhas ou informações de cartão de crédito, onde e como os dados são armazenados é de importância vital.

O armazenamento de sessões é controlado por uma única linha do CakePHP: Configure::write('Session.save', 'php');. Essa linha, localizada no arquivo /app/config/core.php, diz ao Cake como as sessões devem ser armazenadas. Há três valores válidos: php (use aquele que o arquivo php.ini indicar), cake (salve os arquivos de sessão no diretório tmp do Cake) e database (use as sessões de banco de dados do Cake).



Voltar para parte superior


Armazenando sessões: cake

Quando esse valor é determinado, as sessões são armazenadas como arquivos na pasta do seu aplicativo. O CakePHP fornece uma pasta em /app/tmp/session com arquivos que parecem com algo como sess_50bfa744a2ab2c98df808f70c893704c. Dentro desses arquivos, variáveis de sessão individuais são armazenadas como texto simples sem criptografia.

O servidor Web Apache tem uma configuração chamada modo seguro que restringe as pastas às quais o Apache tem acesso. Em geral, o Apache só pode ler o que estiver no docroot do site, com algumas exceções para arquivos de biblioteca. Nesta série, você instalou o CakePHP puxando o diretório inteiro no diretório DocumentRoot do Apache (neste caso, o diretório /webroot). Sem dúvida, esse é um modo simples de instalar a estrutura, mas não mais seguro, e a razão é a seguinte: Ao configurar o manuseio de sessão para cake, você está armazenando variáveis de sessões em um diretório que pode ser acessado diretamente pelo navegador. Se seu site for comprometido de tal forma que o invasor faça o Apache retornar arquivos arbitrários, os dados de sessão de cada usuário ficarão vulneráveis (embora essa talvez seja a menor das suas preocupações). O Cake faz um ótimo trabalho ao proteger esses arquivos mesmo que tudo esteja no DocumentRoot, mas o ideal é instalar de forma mais segura tornando o diretório app/webroot seu diretório DocumentRoot. Isso deve manter off-line os arquivos de sessão do Cake.

é importante notar que você não pode controlar as permissões nesses arquivos de sessão. Eles terão exatamente o mesmo usuário e permissões de grupo que PHP concedeu. Em alguns sistemas, essa também pode ser uma vulnerabilidade de segurança.

Vantagens:

  • As variáveis de sessão são armazenadas dentro do Cake e, assim, todo o aplicativo continua em um só lugar.
  • Os arquivos de sessão podem ser lidos por um navegador de texto, possivelmente para depuração (é pouco provável que tenha utilidade).
  • Iniciar e acessar uma sessão não exige conexão com o banco de dados (é pouco provável que seja útil, visto que acessar modelos no CakePHP inicia uma sessão PHP).

Desvantagens:

  • Qualquer arquivo armazenado em DocumentRoot pode ser comprometido se o servidor Web for comprometido.
  • Os arquivos de sessão têm as mesmas permissões concedidas ao PHP.
  • Servidores Web com equilíbrio de carga que não compartilham um sistema de arquivos não podem compartilhar o acesso a arquivos de sessão, fazendo com que estas sejam desativadas misteriosamente a menos que se usem sessões persistentes.


Voltar para parte superior


Armazenando sessões: database

Se as informações da sessão que você está armazenando precisarem de um nível maior de segurança ou maior controle de permissões, as sessões de banco de dados serão melhores. Configurando Session_save para database, você está dizendo ao CakePHP para armazenar toda informação de variável serializada em uma tabela no banco de dados com o restante do seu aplicativo.

Antes de poder usar sessões de banco de dados com o CakePHP, você deve criar a tabela. Fique à vontade para experimentá-la no Tor. Por padrão, o nome da tabela é cake_sessions, embora isso possa ser alterado no arquivo app/config/core.php. Será preciso tirar os comentários das linhas Configure::write na Session.table e no Session.database a fim de usar o armazenamento da sessão de banco de dados. O esquema dessa tabela é armazenado em app/config/sql/sessions.sql. O esquema incluído no CakePHP V1.2.0.x é mostrado abaixo.


Listagem 9. Criar a tabela cake_sessions
                    
CREATE TABLE cake_sessions (
  id varchar(255) NOT NULL default '',
  data text,
  expires int(11) default NULL,
  PRIMARY KEY  (id)
);
                

Após ter criado a tabela e configurado Session.save para database, tente fazer o login no Tor em /users/login. Após fazer o login, verifique o banco de dados para ver se sua sessão apareceu. Deve haver uma única linha com a seguinte aparência:

id                                 data                                expires
50bfa744a2ab2c98df808f70c893704c   Config|a:3:{s:4:"rand";i:94427...   1164661678
                

Armazenar as sessões no banco de dados trata diretamente de todas as três desvantagens alistadas no método acima. Primeiro, o Apache em geral não tem acesso direto ao banco de dados, de modo que comprometer o servidor Web não expõe os arquivos de sessão. Segundo, as permissões do banco de dados podem ser configuradas explicitamente para o seu aplicativo, e você pode até restringir o acesso a determinado host. Terceiro, os servidores com equilíbrio de carga têm acesso compartilhado com a tabela de sessão sem trabalho extra da sua parte.

Para a maioria dos grandes aplicativos, as sessões de bancos de dados são essenciais porque permitem o máximo de segurança com o mínimo de esforço.

Vantagens:

  • Simples de configurar — exige apenas uma tabela extra no seu banco de dados.
  • Uma perda de segurança no servidor Web provavelmente não resultará em comprometimento das sessões.
  • As sessões podem ser compartilhadas mais facilmente entre servidores com equilíbrio de carga.

Desvantagens:

  • Usar o banco de dados para armazenar sessões acrescenta-lhe um pouco de overhead. Isso pode se acumular.
  • As sessões ainda são armazenadas em texto simples no banco de dados; os backups do banco de dados podem fazer com que dados sensíveis sejam armazenados por períodos prolongados.
  • Dependendo de como seu banco de dados está configurado, as comunicações entre seu aplicativo e o banco de dados podem não ser seguras. Se o seu banco de dados não estiver em localhost, ou não está em um canal seguro, como VPN, é possível que as comunicações fiquem comprometidas.


Voltar para parte superior


Armazenando sessões: php

O método final de armazenar sessões é usar qualquer manuseio de sessão que o PHP estiver configurado para usar. Por padrão, o PHP vai gravar suas sessões como arquivos similares à configuração cake para Session.save. Uma das principais diferenças é que em vez de salvar variáveis de sessão dentro do aplicativo do Cake, elas são geralmente armazenadas em um diretório temporário em outra parte do sistema de arquivos. Isso pode ser ou não ser preferível a ter sessões armazenadas no mesmo diretório do seu site.

Ao configurar as sessões para serem armazenadas via PHP, você dá mais controle a sessões por PHP, em vez de por Cake. O PHP lhe permite cancelar várias funções de manipulador de sessão, essencialmente cancelando o modo como as sessões são armazenadas em um método à sua escolha. Pode ser armazenamento de sessões em um banco de dados separado, em um canal seguro customizado, ou qualquer outro método doido que você inventar.

Se você precisar mudar o modo como o manuseio de sessão é feito no PHP, há uma única função, session_set_save_handler, que controla a função de retorno de chamada de sessão. Como se passa a essa função o nome das funções que abrem, fecham, leem e gravam na sessão é demonstrado abaixo. Uma análise detalhada da função session_set_save_handler está fora do escopo deste artigo (veja os Recursos).


Listagem 10. Redefinindo como o PHP armazena sessões
                    
function open($save_path, $session_name)
{
  global $sess_save_path;
 
  $sess_save_path = $save_path;
  return(true);
}

function read($id)
{
  global $sess_save_path;
 
  $sess_file = "$sess_save_path/sess_$id";
  return (string) @file_get_contents($sess_file);
}

...

session_set_save_handler("open", "close", "read", "write", "destroy", "gc");

As funções de manuseio de sessão são redefinidas pelas funções do PHP: session_start(). Usar esse método tem algumas vantagens.

Vantagens:

  • é flexível. Qualquer método de armazenamento suportado pelo PHP.
  • Se você não cancelar as funções de manuseio de sessão, as sessões serão armazenadas do mesmo modo que todos os outros aplicativos no seu servidor.

Desvantagem:

  • Visto que o PHP é configurado para armazenar sessões no diretório tmp por padrão, você pode encontrar algumas das desvantagens descritas acima em "Armazenando sessões: 'cake'."

Decidir que método usar para manusear o armazenamento de sessões nem sempre é simples. Na maior parte do tempo, deixar o PHP manusear suas sessões não causa problemas. Mas no fim das contas, você terá de tomar essa decisão com base nas peculiaridades do seu aplicativo.

Na próxima seção, analisaremos o componente do Manipulador de Solicitação e como você pode usá-lo para acrescentar a funcionalidade do Ajax ao seu aplicativo.



Voltar para parte superior



Ir para a página anteriorPágina 3 de 9 Ir para a próxima página