PHP:
Cookies e Sessões
Programação de Servidores
Marx Gomes Van der Linden
Protocolo HTTP


O protocolo HTTP não tem conceito de
sessões.
Modelo simples de Requisição e Resposta.
http://marx.vanderlinden.com.br/
2
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/
3
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
outros sites.
http://marx.vanderlinden.com.br/
4
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/
5
Cookies
http://marx.vanderlinden.com.br/
6
Cookies
http://marx.vanderlinden.com.br/
7
Cookies
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/
9
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.
http://marx.vanderlinden.com.br/
10
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
aceitar o cookie.
http://marx.vanderlinden.com.br/
11
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>
http://marx.vanderlinden.com.br/
</html>
12
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,enus;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/
13
Connection: keep-alive
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
Content-Type: text/html
http://marx.vanderlinden.com.br/
14
Saída
<html>
<head>
<title>Cookies, página 1</title>
</head>
<body>Cookie enviado com sucesso</body>
</html>
http://marx.vanderlinden.com.br/
15
$_COOKIE


O interpretador PHP automaticamente organiza
os cookies enviados pelo usuário ao servidor,
através do array $_COOKIE.
Formato:
 $_COOKIE[$nome] // retorna $valor
http://marx.vanderlinden.com.br/
16
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.";
?>
</body></html>
http://marx.vanderlinden.com.br/
17
RequisiçãoHTTP/1.1
HTTP
GET /exemplo/pagina2.php
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,enus;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
http://marx.vanderlinden.com.br/
18
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
Content-Type: text/html
http://marx.vanderlinden.com.br/
19
Saída
<html>
<head>
<title>Cookies, página 2</title>
</head>
<body>
Seu nome é Milhouse Van
Houten.</body></html>
http://marx.vanderlinden.com.br/
20
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");
setcookie("valor[empresa]", "Microsoft");
http://marx.vanderlinden.com.br/
21
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>
empresa: Microsoft
<br>
http://marx.vanderlinden.com.br/
22
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
o navegador
http://marx.vanderlinden.com.br/
23
Tempo de expiração

Cookie que expira em 1 hora:
setcookie(
'login','milhouse', time() + 60*60

Cookie que expira em 1 dia:
setcookie(
'login','krusty', time() + 60*60*24

);
);
Cookie que expira do dia 12 de outubro de
2010
setcookie(
'login','flanders',
http://marx.vanderlinden.com.br/
mktime(12,0,0, 10,12,2010)
);
24
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

'/' → Domínio inteiro
http://marx.vanderlinden.com.br/
25
Diretório de aplicação do Cookie

Cookie válido para todo o domínio
setcookie('login','burns', 0, '/' );


www.exemplo.com

www.exemplo.com/dir1/springfield
Cookie válido para um diretório
setcookie('login','barney',
time()+60*60, '/moe' );


www.exemplo.com/moe
http://marx.vanderlinden.com.br/
www.exemplo.com/moe/tavern
26
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/
27
Domínio de aplicação do Cookie

Cookie válido para todo o domínio
setcookie('login','burns', 0,
'/', '.exemplo.com' );

www.exemplo.com

www.exemplo.com/dir1/springfield

meusite.exemplo.com/shelbyville
http://marx.vanderlinden.com.br/
28
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:
setcookie('login','burns', 0, '/' );

Excluindo:
setcookie('login','', 0, '/' );
http://marx.vanderlinden.com.br/
29
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.


http://marx.vanderlinden.com.br/
30
Sessões

PHP fornece um mecanismo de sessões.

Quase todos os dados ficam armazenados no
servidor.
http://marx.vanderlinden.com.br/
31
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.
http://marx.vanderlinden.com.br/
32
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
Sempre returna true
http://marx.vanderlinden.com.br/
33
$_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
setcookie.
http://marx.vanderlinden.com.br/
34
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']++ ?>.
</body>
</html>
http://marx.vanderlinden.com.br/
35
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,enus;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/
36
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, mustrevalidate, 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/
37
Content-Type: text/html
2a Requisição HTTP
GET /delme/exemplo.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; U; Linux i686; ptBR; 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,enus;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
http://marx.vanderlinden.com.br/
38
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, mustrevalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 110
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html
http://marx.vanderlinden.com.br/
39
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.
http://marx.vanderlinden.com.br/
40
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/
41
session_id


Sintaxe:
session_id()

Retorna o ID da seção atual, ou '', caso não
haja sessão aberta.
http://marx.vanderlinden.com.br/
42
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/
43
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.
http://marx.vanderlinden.com.br/
44
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/
45
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_start( );
http://marx.vanderlinden.com.br/
46
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);
session_start( );
http://marx.vanderlinden.com.br/
47
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
passar por outro usuário.
http://marx.vanderlinden.com.br/
48
Funções de Hash
http://marx.vanderlinden.com.br/
49
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)
http://marx.vanderlinden.com.br/
50
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/
51
$_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.
http://marx.vanderlinden.com.br/
52
$_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

'REMOTE_ADDR' → Endereço IP do cliente
http://marx.vanderlinden.com.br/
53
$_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>http://marx.vanderlinden.com.br/
54
REMOTE_ADDR: 127.0.0.1<br>
Sessão Segura (1/2)
<?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";
}
else
http://marx.vanderlinden.com.br/
$msg .= "Continuando..."; ?>
55
Sessão Segura
<html>
<head><title>Sessões</title></head>
<body>
<?php echo $msg ?>
</body>
</html>
http://marx.vanderlinden.com.br/
56
Saída

Primeira execução:
OK!<br>
Continuando sessão

Execuções seguintes:
Continuando sessão

Tentativa de ataque:
Erro! Por favor, faça o login novamente.
http://marx.vanderlinden.com.br/
57
Download

13 - PHP: Cookies e Sessões