PHP:
Cookies e Sessões
Programação de Servidores Marx Gomes Van der Linden
http://marx.vanderlinden.com.br/ 2
Protocolo HTTP
O protocolo HTTP não tem conceito de sessões.
Protocolo HTTP
Tipicamente, vários usuários estão acessando o servidor web ao mesmo tempo.
HTTP não define uma maneira direta de se rastrear cada usuário e dar continuidade
individual às atividades de requisições anteriores.
http://marx.vanderlinden.com.br/ 4
Cookies
Um Cookie é um arquivo de texto que pode ser criado pelo navegador, a pedido do servidor
web.
Cada cookie tem um conjunto de variáveis: nome=valor
Todo cookie é necessariamente associado ao um site (ou domínio) que o criou e,
teoricamente, não pode ser acessado por
Cookies
O cookie é reenviado automaticamente ao servidor a cada nova visita à mesma página.
Um cookie pode conter uma data de expiração (opcional)
Default: Cookie é apagado ao se fechar o navegador.
http://marx.vanderlinden.com.br/ 6
http://marx.vanderlinden.com.br/ 8
Usos de Cookies
Armazenar itens no "carrinho de compras". Armazenar informações de autenticação. Guardar configurações do usuário.
Permitir continuidade no uso de uma aplicação web.
http://marx.vanderlinden.com.br/ 10
setcookie
Para incluir na resposta HTTP uma solicitação para que o navegador crie um cookie, basta utilizar a função setcookie.
Sintaxe (simplificada):
setcookie($nome, $valor)
Returna true em caso de sucesso, false em caso de erro.
setcookie
Deve ser usado antes de enviar qualquer dado pertencente ao corpo da mensagem! (inclusive espaços em branco).
Não há garantias de que o navegador vai
http://marx.vanderlinden.com.br/ 12
pagina1.php
<?php
$b = setcookie('nome',
'Milhouse Van Houten');
?>
<html> <head>
<title>Cookies, página 1</title> </head>
<body><?php
if($b)
echo "Cookie enviado com sucesso";
else
echo "Erro ao enviar o cookie.";
?></body> </html>
Requisição HTTP
GET /exemplo/pagina1.php HTTP/1.1 Host: localhost
User-Agent: Mozilla/5.0 (X11; U; Linux i686; pt-BR; rv:1.9.0.1) Gecko/2008072820 Firefox/3.0.1 Accept: text/html,application/xhtml+xml,application/x ml;q=0.9,*/*;q=0.8 Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300
http://marx.vanderlinden.com.br/ 14
Resposta HTTP (Cabeçalho)
HTTP/1.x 200 OK
Date: Fri, 19 Sep 2008 21:01:36 GMT Server: Apache/2.2.8 (Ubuntu)
PHP/5.2.4-2ubuntu5.3 with Suhosin-Patch X-Powered-By: PHP/5.2.4-2ubuntu5.3
Set-Cookie: nome=Milhouse+Van+Houten
Content-Length: 107
Keep-Alive: timeout=15, max=100 Connection: Keep-Alive
Saída
<html> <head>
<title>Cookies, página 1</title> </head>
<body>Cookie enviado com sucesso</body> </html>
http://marx.vanderlinden.com.br/ 16
$_COOKIE
O interpretador PHP automaticamente organiza os cookies enviados pelo usuário ao servidor, através do array $_COOKIE.
Formato:
pagina2.php
<html> <head>
<title>Cookies, página 2</title> </head>
<body>
<?php
if(isset($_COOKIE['nome']))
echo "Seu nome é $_COOKIE[nome].";
else
echo "Eu não sei o seu nome.";
?>
http://marx.vanderlinden.com.br/ 18
Requisição HTTP
GET /exemplo/pagina2.php HTTP/1.1 Host: localhost
User-Agent: Mozilla/5.0 (X11; U; Linux i686; pt-BR; rv:1.9.0.1) Gecko/2008072820 Firefox/3.0.1 Accept: text/html,application/xhtml+xml,application/x ml;q=0.9,*/*;q=0.8 Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Cookie: nome=Milhouse+Van+Houten Cache-Control: max-age=0
Resposta HTTP (Cabeçalho)
HTTP/1.x 200 OK
Date: Fri, 19 Sep 2008 21:07:02 GMT Server: Apache/2.2.8 (Ubuntu)
PHP/5.2.4-2ubuntu5.3 with Suhosin-Patch X-Powered-By: PHP/5.2.4-2ubuntu5.3
Content-Length: 112
Keep-Alive: timeout=15, max=100 Connection: Keep-Alive
http://marx.vanderlinden.com.br/ 20
Saída
<html> <head>
<title>Cookies, página 2</title> </head>
<body>
Seu nome é Milhouse Van Houten.</body></html>
Cookies como arrays
Para armazenar no cliente um cookie que será lido como um array, basta utilizar a notação de arrays.
setcookie("valor[nome]", "Bill");
setcookie("valor[sobrenome]", "Gates");
http://marx.vanderlinden.com.br/ 22
Cookies como arrays
Depois, é possível usar o resultado do cookie recebido de volta como um array comum.
if (isset($_COOKIE['valor'])) { foreach (
$_COOKIE['valor'] as $indice => $valor
)
echo "$indice: $valor <br>\n";
}
nome: Bill <br>
sobrenome: Gates <br>
Tempo de expiração
Para evitar que o cookie seja excluído quando o navegador for fechado, é necessário
especificar um tempo de expiração. Sintaxe completa:
setcookie($nome, $valor,
[$dataexpira], [$caminho], [$domínio])
Se $dataexpira não for especificado ou igual a 0, será excluído quando se fechar
http://marx.vanderlinden.com.br/ 24
Tempo de expiração
Cookie que expira em 1 hora:
Cookie que expira em 1 dia:
Cookie que expira do dia 12 de outubro de 2010 setcookie( 'login','milhouse', time() + 60*60 ); setcookie( 'login','krusty', time() + 60*60*24 ); setcookie( 'login','flanders', mktime(12,0,0, 10,12,2010) );
Diretório de aplicação do Cookie
O terceiro parâmetro de setcookie serve para especificar a partir de que diretório, na
estrutura de arquivos do servidor web, o cookie deve ser aplicado.
Padrão: apenas diretório atual
http://marx.vanderlinden.com.br/ 26
Diretório de aplicação do Cookie
Cookie válido para todo o domínio
www.exemplo.com
www.exemplo.com/dir1/springfield
Cookie válido para um diretório
www.exemplo.com/moe
www.exemplo.com/moe/tavern
setcookie('login','burns', 0, '/' );
setcookie('login','barney',
Domínio de aplicação do Cookie
Por padrão os cookies só são enviados para sites que tenham exatamente o mesmo
domínio (incluindo subdomínio)
www.exemplo.com ≠ meusite.exemplo.com
O quarto parâmetro indica para que partes do domínio da URL o cookie deverá ser enviado.
Não é possível especificar um domínio diferente daquele do site que registra o cookie!
http://marx.vanderlinden.com.br/ 28
Domínio de aplicação do Cookie
Cookie válido para todo o domínio
www.exemplo.com
www.exemplo.com/dir1/springfield meusite.exemplo.com/shelbyville
setcookie('login','burns', 0, '/', '.exemplo.com' );
Excluindo um cookie
Para excluir um cookie, basta passar um novo cookie com exatamente os mesmos
parâmetros já passados, mas valor igual à
string vazia. Criando:
Excluindo:
http://marx.vanderlinden.com.br/ 30
Características dos Cookies
Todas as informações ficam armazenadas no cliente.
O servidor não tem um controle preciso de que cookies estão armazenados para cada usuário.
Todas os dados precisam ser repassados novamente a cada requisição HTTP feita pelo cliente.
Cookies podem ser desativados, excluídos e modificados pelo cliente.
Sessões
PHP fornece um mecanismo de sessões. Quase todos os dados ficam armazenados no
http://marx.vanderlinden.com.br/ 32
Sessões
Quando a sessão inicia, o servidor gera um ID, que é uma string alfanumérica aleatória única (PHPSESSID) para identificar o cliente.
O cliente armazena a ID como um cookie.
Em todas as requisições seguintes, o cliente
envia ao servidor apenas o cookie referente ao seu ID.
A partir dos IDs, o servidor identifica e diferencia cada cliente.
session_start()
Para iniciar (ou continuar) uma sessão, basta usar a função session_start
Sintaxe:
session_start()
Deve ser usado antes de qualquer saída do corpo da mensagem
http://marx.vanderlinden.com.br/ 34
$_SESSION
Para ler e configurar variáveis de sessões, utiliza-se o array $_SESSION.
Não há análogo em sessões à função
exemplo.php
<?php session_start(); ?> <html> <head> <title>Sessões</title> </head> <body> <?php if(!isset($_SESSION['visitas'])) $_SESSION['visitas'] = 0; ?>Esta é a sua visita número
<?php echo $_SESSION['visitas']++ ?>.
http://marx.vanderlinden.com.br/ 36
1a Requisição HTTP
GET /delme/exemplo.php HTTP/1.1 Host: localhost
User-Agent: Mozilla/5.0 (X11; U; Linux i686; pt-BR; rv:1.9.0.1) Gecko/2008072820 Firefox/3.0.1 Accept: text/html,application/xhtml+xml,application/x ml;q=0.9,*/*;q=0.8 Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive
1a Resposta HTTP (Cabeçalho)
HTTP/1.x 200 OK
Date: Fri, 19 Sep 2008 22:17:44 GMT Server: Apache/2.2.8 (Ubuntu)
PHP/5.2.4-2ubuntu5.3 with Suhosin-Patch X-Powered-By: PHP/5.2.4-2ubuntu5.3
Set-Cookie:
PHPSESSID=c7abd60716ef5c9df79f3788767aaec5;
path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 110
Keep-Alive: timeout=15, max=100 Connection: Keep-Alive
http://marx.vanderlinden.com.br/ 38
2a Requisição HTTP
GET /delme/exemplo.php HTTP/1.1 Host: localhost
User-Agent: Mozilla/5.0 (X11; U; Linux i686; pt-BR; rv:1.9.0.1) Gecko/2008072820 Firefox/3.0.1 Accept: text/html,application/xhtml+xml,application/xml; q=0.9,*/*;q=0.8 Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Cookie: PHPSESSID=c7abd60716ef5c9df79f3788767aaec5 Cache-Control: max-age=0
2a Resposta HTTP
HTTP/1.x 200 OK
Date: Fri, 19 Sep 2008 22:19:46 GMT Server: Apache/2.2.8 (Ubuntu)
PHP/5.2.4-2ubuntu5.3 with Suhosin-Patch X-Powered-By: PHP/5.2.4-2ubuntu5.3
Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 110
Keep-Alive: timeout=15, max=100 Connection: Keep-Alive
http://marx.vanderlinden.com.br/ 40
session_set_cookie_params
É possível configurar os parâmetros do cookie usado para armazenar o ID da sessão.
Sintaxe:
session_set_cookie_params(
$dataexpira, [$caminho], [$domínio])
A sintaxe dos parâmetros é similar às da função setcookie.
session_name
A função session_name muda o nome do cookie que identifica o código da sessão.
Deve ser chamado antes de session_start. Sintaxe:
session_name($novonome)
Return true em caso de sucesso; false em erro.
http://marx.vanderlinden.com.br/ 42
session_id
Sintaxe:
session_id()
Retorna o ID da seção atual, ou '', caso não haja sessão aberta.
session_regenerate_id
Sintaxe:
session_regenerate_id()
Gera um novo ID para a sessão atual.
Envia uma novo requisição de Cookie ao cliente, sem quebrar a sessão.
Precisa ser chamado antes de qualquer saída no corpo da resposta HTTP.
Return true em caso de sucesso; false em erro.
http://marx.vanderlinden.com.br/ 44
Configurando sessões
Por padrão:
Uma sessão continua ativa caso seja
acessada pelo usuário ao menos 1 vez a cada 24 minutos.
Sessões não servem para armazenar dados permanentes!
Cada vez que session_start é chamada, há uma probabilidade de 1% de que o PHP vai varrer todas as sessões ativas, e excluir as que expiraram.
ini_set
A função ini_set serve para mudar
temporariamente alguma configuração do PHP. Sintaxe:
ini_set($variável, $novovalor)
Return true em caso de sucesso; false em erro.
http://marx.vanderlinden.com.br/ 46
session.gc_maxlifetime
Especifica o tempo (em segundos) máximo que uma sessão deve durar, esperando pelo
usuário.
Padrão: 1440 (24 minutos).
Deve ser modificada antes de session_start()
ini_set('session.gc_maxlifetime', 600);
session.gc_probability
Especifica a probabilidade (em %) de que o PHP vai fazer a verificação e limpeza das sessões expiradas, a cada chamada de
session_start.
Padrão: 1
Também deve ser modificada antes de
session_start
ini_set('session.gc_probability', 100);
http://marx.vanderlinden.com.br/ 48
Segurança
Problema de segurança:
A ID da sessão pode ser interceptada por alguém que esteja monitorando a rede.
Se outra pessoa usar a mesma ID para fazer requisições ao servidor, pode fazer se
http://marx.vanderlinden.com.br/ 50
Funções de Hash
PHP implementa as funções de hash mais comuns:
md5($string) sha1($string)
hash($algoritmo, $string)
(Função genérica que implementa vários algoritmos)
md5
echo md5("The book is on the table"), " <br>\n";
echo md5("The book is on the table."), " <br>\n";
0c29bf0f928decfbf91070fa4affb0c4 <br> 1f683fe1cd7977cdd056ddc25d6bd8f8 <br>
http://marx.vanderlinden.com.br/ 52
$_SERVER
O array $_SERVER contém informações fornecidas pelo servidor web, como
cabeçalhos, caminhos de arquivo e configurações.
Os índices do array são fixos e seus valores não podem ser modificados.
$_SERVER
Exemplos:
'PHP_SELF' → Nome do script atual
'SERVER_ADDR' → Endereço IP do servidor
'SERVER_NAME' → Nome do servidor
'HTTP_USER_AGENT' → Configurações do cliente
http://marx.vanderlinden.com.br/ 54
$_SERVER
$keys = array( 'PHP_SELF', 'SERVER_ADDR', 'SERVER_NAME', 'HTTP_USER_AGENT', 'REMOTE_ADDR', ); foreach($keys as $k) echo "$k: $_SERVER[$k]<br>\n"; PHP_SELF: /exemplo/exemplo.php<br> SERVER_ADDR: 127.0.0.1<br> SERVER_NAME: localhost<br>HTTP_USER_AGENT: Mozilla/5.0 (X11; U; Linux i686; pt-BR; rv:1.9.0.1) Gecko/2008072820
Firefox/3.0.1<br>
<?php session_start(); $md5 = md5( $_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR'] ); if (!isset($_SESSION['md5'])) { session_regenerate_id(); $_SESSION['md5'] = $md5; $msg = "Bem-vindo!<br>\n"; } if ($_SESSION['md5'] != $md5) { $_SESSION = array(); $_SESSION['md5'] = $md5;
$msg = "Erro! Por favor, faça o login novamente.<br>\n";
}
http://marx.vanderlinden.com.br/ 56