Fundamentos do PHP

0/25 aulas0%
pratica

Gerenciamento de sessões e cookies para persistência de dados

Aprenda sobre gerenciamento de sessões e cookies para persistência de dados

50 min
Aula 4 de 5

Gerenciamento de Sessões e Cookies para Persistência de Dados 🍪🔑

Olá, futuro(a) desenvolvedor(a) PHP! 👋 Nesta aula prática, vamos mergulhar em dois mecanismos cruciais para a persistência de dados em aplicações web: Cookies e Sessões. Eles são a espinha dorsal de funcionalidades como "lembrar-me", carrinhos de compra e áreas de login, permitindo que sua aplicação "lembre" informações sobre um usuário entre diferentes requisições HTTP.

Vamos entender como eles funcionam, como utilizá-los de forma eficaz e segura, e colocar a mão na massa com alguns exercícios! 🚀

1. Introdução: Por que Cookies e Sessões?

O protocolo HTTP, por sua natureza, é stateless (sem estado). Isso significa que cada requisição HTTP de um navegador para um servidor é independente das outras. O servidor não "lembra" o que aconteceu na requisição anterior.

Imagine um site de e-commerce:

  • Você adiciona um item ao carrinho.
  • Navega para outra página.
  • Volta ao carrinho e o item ainda está lá.
  • Você faz login e permanece logado enquanto navega.

Como isso é possível se o HTTP não tem estado? É aqui que entram os Cookies e as Sessões! Eles nos fornecem maneiras de manter o "estado" do usuário, tornando a experiência de navegação mais fluida e personalizada.

2. Cookies: Pequenos Pacotes de Informação no Navegador 🍪

O que são Cookies?

Cookies são pequenos arquivos de texto que um servidor web envia ao navegador do usuário. O navegador armazena esses cookies e os envia de volta ao servidor em cada requisição subsequente para o mesmo domínio. Eles são ideais para armazenar pequenas quantidades de dados, como preferências do usuário ou um identificador de sessão.

Como Funcionam?

  1. Servidor envia Cookie: Quando o servidor PHP processa uma requisição, ele pode incluir um cabeçalho Set-Cookie na resposta HTTP.
  2. Navegador armazena Cookie: O navegador recebe esse cabeçalho e armazena o cookie.
  3. Navegador envia Cookie de volta: Em todas as requisições futuras para o mesmo domínio, o navegador inclui o cookie no cabeçalho Cookie da requisição.
  4. Servidor lê Cookie: O servidor PHP pode acessar o cookie enviado pelo navegador.

Gerenciando Cookies com PHP

O PHP oferece a função setcookie() para enviar cookies ao navegador e a superglobal $_COOKIE para acessar os cookies recebidos.

setcookie(): Definindo um Cookie

A função setcookie() deve ser chamada antes de qualquer saída HTML para o navegador.

<?php
// Sintaxe básica: setcookie(name, value, expire, path, domain, secure, httponly);
 
// Exemplo 1: Cookie simples que expira quando o navegador é fechado
setcookie("nome_usuario", "Alice");
 
// Exemplo 2: Cookie com tempo de expiração (1 hora a partir de agora)
// time() + 3600 segundos (1 hora)
setcookie("preferencia_tema", "dark", time() + 3600);
 
// Exemplo 3: Cookie com tempo de expiração, caminho e segurança (apenas HTTPS)
// O cookie estará disponível em todo o site ('/')
// O cookie será enviado apenas em conexões HTTPS (true)
setcookie("token_sessao", "abc123xyz", time() + (86400 * 30), "/", "seu-dominio.com", true, true);
// 86400 segundos = 1 dia
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title>Definindo Cookies</title>
</head>
<body>
    <h1>Cookies Definidos!</h1>
    <p>Verifique as ferramentas de desenvolvedor do seu navegador para-los.</p>
</body>
</html>
  • name: O nome do cookie.
  • value: O valor a ser armazenado.
  • expire: O tempo em que o cookie expira. Use time() + segundos para definir um futuro. Se omitido ou 0, expira ao fechar o navegador.
  • path: O caminho no servidor onde o cookie estará disponível (e.g., / para todo o site).
  • domain: O domínio para o qual o cookie é válido (e.g., seu-dominio.com).
  • secure: Se true, o cookie só será enviado em conexões HTTPS.
  • httponly: Se true, o cookie não pode ser acessado via JavaScript, o que ajuda a prevenir ataques XSS. Altamente recomendado para cookies sensíveis!

$_COOKIE: Acessando um Cookie

Depois que um cookie é definido e o navegador o envia de volta, você pode acessá-lo através da superglobal $_COOKIE.

<?php
// Certifique-se de que este código esteja em uma página acessada APÓS o cookie ter sido definido
// e enviado pelo navegador.
 
$nome_usuario = $_COOKIE['nome_usuario'] ?? 'Visitante';
$preferencia_tema = $_COOKIE['preferencia_tema'] ?? 'light';
 
echo "<h2>Boas-vindas, " . htmlspecialchars($nome_usuario) . "!</h2>";
echo "<p>Seu tema preferido é: " . htmlspecialchars($preferencia_tema) . "</p>";
 
// Exemplo de como usar a preferência para estilizar
if ($preferencia_tema === 'dark') {
    echo '<style>body { background-color: #333; color: #f0f0f0; }</style>';
} else {
    echo '<style>body { background-color: #fff; color: #333; }</style>';
}
 
echo "<h3>Todos os cookies recebidos:</h3>";
echo "<pre>";
print_r($_COOKIE);
echo "</pre>";
?>

Deletando um Cookie

Para deletar um cookie, você chama setcookie() novamente com o mesmo name e path, mas define o tempo de expiração para um valor no passado.

<?php
// Para deletar 'nome_usuario', defina a expiração para um tempo no passado
setcookie("nome_usuario", "", time() - 3600); // 1 hora no passado
 
// Para deletar 'preferencia_tema', certifique-se de usar os mesmos parâmetros (path, domain, etc.) se foram definidos
setcookie("preferencia_tema", "", time() - 3600, "/");
 
echo "<p>Cookies 'nome_usuario' e 'preferencia_tema' foram enviados para expirar.</p>";
?>

Segurança e Cookies

  • HTTPS (Secure flag): Sempre use HTTPS em produção para proteger os cookies de interceptação.
  • HttpOnly: Previne acesso a cookies via JavaScript, mitigando XSS.
  • SameSite: Impede que o navegador envie o cookie em requisições cross-site, protegendo contra CSRF. (Ex: setcookie("nome", "valor", ['samesite' => 'Lax']); ou setcookie("nome", "valor", time() + 3600, "/", "", false, true, ['samesite' => 'Lax']); a partir do PHP 7.3)
  • Não armazene dados sensíveis: Cookies são armazenados no cliente e podem ser facilmente modificados ou roubados. Nunca armazene senhas, informações financeiras ou dados confidenciais diretamente em cookies.

3. Sessões: Dados Armazenados no Servidor 🔑

O que são Sessões?

Sessões fornecem uma maneira de armazenar dados do usuário no servidor por um período limitado de tempo. Ao contrário dos cookies, os dados da sessão não são enviados ao navegador. Em vez disso, o servidor cria um identificador único para cada sessão (o Session ID), que é então enviado ao navegador, geralmente via um cookie (o PHPSESSID).

Como Funcionam?

  1. Início da Sessão: Quando session_start() é chamado, o PHP verifica se um Session ID válido foi enviado pelo navegador.
  2. Novo Session ID: Se não houver Session ID ou ele for inválido, o PHP gera um novo Session ID e o armazena em um cookie (por padrão, PHPSESSID).
  3. Carregamento/Criação de Dados: O PHP carrega os dados da sessão associados a esse Session ID do armazenamento do servidor (geralmente arquivos temporários). Se for uma nova sessão, um novo arquivo é criado.
  4. Acesso e Modificação: Os dados da sessão ficam disponíveis através da superglobal $_SESSION.
  5. Salvamento da Sessão: No final da execução do script, o PHP salva as modificações feitas em $_SESSION de volta ao armazenamento do servidor.

Gerenciando Sessões com PHP

session_start(): Iniciando uma Sessão

Esta função DEVE ser chamada no início de cada script que precisa acessar ou modificar dados de sessão, e antes de qualquer saída HTML.

<?php
// Inicia a sessão. Se uma sessão já existe, ela é retomada.
// Se não, uma nova sessão é iniciada.
session_start();
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title>Gerenciando Sessões</title>
</head>
<body>
    <h1>Página de Sessão</h1>
<?php
// Verifica se a variável 'contador' existe na sessão
if (!isset($_SESSION['contador'])) {
    $_SESSION['contador'] = 0; // Inicializa se não existir
}
 
$_SESSION['contador']++; // Incrementa o contador a cada visita
 
echo "<p>Você visitou esta página " . $_SESSION['contador'] . " vezes nesta sessão.</p>";
 
// Armazenando mais dados na sessão
$_SESSION['usuario_logado'] = 'Carlos';
$_SESSION['carrinho'] = ['item1' => 2, 'item2' => 1];
 
echo "<p>Usuário logado: " . htmlspecialchars($_SESSION['usuario_logado']) . "</p>";
echo "<p>Itens no carrinho: " . count($_SESSION['carrinho']) . "</p>";
 
echo "<h3>Dados da Sessão:</h3>";
echo "<pre>";
print_r($_SESSION);
echo "</pre>";
 
echo '<p><a href="pagina_seguinte.php">Ir para a próxima página</a></p>';
?>
</body>
</html>

$_SESSION: Armazenando e Acessando Dados

$_SESSION é uma superglobal (um array associativo) que você pode usar para armazenar e recuperar qualquer tipo de dado PHP.

<?php
session_start();
 
// Acessando dados da sessão
$usuario = $_SESSION['usuario_logado'] ?? 'Convidado';
$carrinho = $_SESSION['carrinho'] ?? [];
 
echo "<h2>Olá, " . htmlspecialchars($usuario) . "!</h2>";
if (!empty($carrinho)) {
    echo "<p>Seu carrinho contém:</p>";
    echo "<ul>";
    foreach ($carrinho as $item => $quantidade) {
        echo "<li>" . htmlspecialchars($item) . " (x" . htmlspecialchars($quantidade) . ")</li>";
    }
    echo "</ul>";
} else {
    echo "<p>Seu carrinho está vazio.</p>";
}
 
echo '<p><a href="sessao_destruir.php">Destruir Sessão</a></p>';
?>

session_unset() e session_destroy(): Destruindo uma Sessão

  • session_unset(): Remove todas as variáveis da superglobal $_SESSION, mas a sessão em si ainda existe no servidor e o cookie de sessão ainda está no navegador.
  • session_destroy(): Destrói todos os dados registrados em uma sessão. Ela não remove as variáveis globais da sessão, nem o cookie de sessão. Você geralmente precisa chamar session_unset() e também remover o cookie de sessão manualmente se quiser uma "limpeza" completa.

Para um logout completo:

<?php
session_start();
 
// 1. Limpa todas as variáveis de sessão
$_SESSION = array(); // Melhor prática para garantir que todas as variáveis são limpas
 
// 2. Se a sessão usa cookies, é importante que o cookie de sessão também seja apagado.
// Isso normalmente é feito definindo seu tempo de expiração para o passado.
// Nota: Isso irá destruir o cookie de sessão, e não apenas os dados da sessão!
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}
 
// 3. Finalmente, destrói a sessão no servidor.
session_destroy();
 
echo "<h2>Sessão destruída com sucesso!</h2>";
echo "<p>Você foi desconectado(a).</p>";
echo '<p><a href="sessao_iniciar.php">Iniciar nova sessão</a></p>';
?>

Segurança e Sessões

  • Session Hijacking: Ataques onde o atacante rouba o Session ID de um usuário legítimo para se passar por ele.
    • Sempre use HTTPS.
    • Use session.cookie_httponly = true no php.ini ou via session_set_cookie_params().
    • Regenere o Session ID em momentos críticos (e.g., após o login) com session_regenerate_id(true).
  • Session Fixation: Ataques onde o atacante força um Session ID específico para o usuário, que ele já conhece.
    • Sempre regenere o Session ID após o login.
  • Tempo de vida da sessão: Configure session.gc_maxlifetime no php.ini para um tempo razoável para que as sessões inativas expirem.

4. Integração: Cookies e Sessões na Prática

A integração entre cookies e sessões é automática no PHP. Quando você chama session_start(), o PHP tenta encontrar um cookie chamado PHPSESSID (o nome padrão) no navegador. Se encontrar e for válido, ele usa esse ID para carregar os dados da sessão correspondentes no servidor. Se não encontrar ou for inválido, ele cria um novo Session ID, armazena os dados da sessão no servidor e envia um novo cookie PHPSESSID para o navegador.

Não é necessário gerenciar o cookie PHPSESSID manualmente! O PHP cuida disso para você. Você só interage com $_SESSION.

Exemplo de Fluxo de Login Básico (Sessão)

Este é um exemplo simplificado. Em um ambiente real, você usaria hash de senhas, validação de entrada, etc.

login.php

<?php
session_start();
 
$mensagem = '';
 
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $usuario_digitado = $_POST['usuario'] ?? '';
    $senha_digitada = $_POST['senha'] ?? '';
 
    // Simulação de verificação de credenciais (NÃO FAÇA ISSO EM PRODUÇÃO!)
    if ($usuario_digitado === 'admin' && $senha_digitada === '12345') {
        $_SESSION['logado'] = true;
        $_SESSION['usuario'] = $usuario_digitado;
        // Regenera o ID da sessão para prevenir Session Fixation
        session_regenerate_id(true);
        header('Location: dashboard.php');
        exit;
    } else {
        $mensagem = 'Usuário ou senha inválidos!';
    }
}
 
// Se o usuário já estiver logado, redireciona para o dashboard
if (isset($_SESSION['logado']) && $_SESSION['logado'] === true) {
    header('Location: dashboard.php');
    exit;
}
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <?php if ($mensagem): ?>
        <p style="color: red;"><?= htmlspecialchars($mensagem) ?></p>
    <?php endif; ?>
    <form action="login.php" method="POST">
        <label for="usuario">Usuário:</label>
        <input type="text" id="usuario" name="usuario" required><br><br>
        <label for="senha">Senha:</label>
        <input type="password" id="senha" name="senha" required><br><br>
        <button type="submit">Entrar</button>
    </form>
</body>
</html>

dashboard.php

<?php
session_start();
 
// Verifica se o usuário está logado
if (!isset($_SESSION['logado']) || $_SESSION['logado'] !== true) {
    header('Location: login.php'); // Redireciona para a página de login se não estiver logado
    exit;
}
 
$usuario = $_SESSION['usuario'] ?? 'Usuário Desconhecido';
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title>Dashboard</title>
</head>
<body>
    <h1>Bem-vindo(a) ao Dashboard, <?= htmlspecialchars($usuario) ?>!</h1>
    <p>Aqui você pode ver o conteúdo exclusivo para usuários logados.</p>
    <p><a href="logout.php">Sair</a></p>
</body>
</html>

logout.php

<?php
session_start();
 
// Limpa todas as variáveis de sessão
$_SESSION = array();
 
// Se a sessão usa cookies, é importante que o cookie de sessão também seja apagado.
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}
 
// Finalmente, destrói a sessão.
session_destroy();
 
header('Location: login.php'); // Redireciona para a página de login
exit;
?>

5. Exercícios e Desafios Práticos 🧑‍💻

Hora de colocar em prática o que aprendemos! Crie os arquivos PHP necessários e teste as funcionalidades.

Desafio 1: Contador de Visitas com Cookie 🍪

Crie uma página PHP que exiba quantas vezes o usuário visitou o site. O contador deve ser armazenado em um cookie que expira em 30 dias.

  • Crie um arquivo contador_cookie.php.
  • No início do arquivo, verifique se o cookie visitas existe.
  • Se não existir, inicialize-o com 1.
  • Se existir, incremente seu valor.
  • Atualize o cookie com o novo valor e o tempo de expiração de 30 dias.
  • Exiba a mensagem "Você visitou esta página X vezes."
  • Adicione um botão ou link para "Resetar Contador" que apague o cookie.

Desafio 2: Preferência de Tema com Cookie (e JavaScript opcional) 🌓

Crie uma página onde o usuário possa escolher entre um tema "claro" e "escuro". A escolha deve ser armazenada em um cookie e persistir entre as visitas.

  • Crie um arquivo tema.php.
  • No início do arquivo, verifique se o cookie tema_preferido existe.
  • Se existir, aplique o tema via CSS inline ou uma classe no <body>.
  • Se não existir, use um tema padrão (e.g., claro).
  • Adicione dois links ou botões para "Tema Claro" e "Tema Escuro".
  • Ao clicar, defina o cookie tema_preferido com a escolha do usuário (expiração de 1 ano) e recarregue a página (ou use JavaScript para aplicar imediatamente).
  • Exiba o tema atual.

Desafio 3: Carrinho de Compras Simples com Sessão 🛒

Desenvolva um sistema de carrinho de compras básico usando sessões.

  • Crie um arquivo produtos.php que lista alguns produtos (e.g., "Camiseta", "Calça", "Tênis") com um botão "Adicionar ao Carrinho" para cada um.
  • Ao clicar em "Adicionar ao Carrinho", o produto deve ser adicionado à superglobal $_SESSION['carrinho']. Se o produto já estiver no carrinho, incremente a quantidade.
  • Crie um arquivo carrinho.php que exiba os itens atualmente no $_SESSION['carrinho'], suas quantidades e um total simples.
  • Em carrinho.php, adicione um link para "Esvaziar Carrinho" que limpe a variável $_SESSION['carrinho'].
  • Certifique-se de que session_start() seja chamado em todos os arquivos relevantes.

Desafio 4: Autenticação Básica com Sessão e Regeneração de ID 🔒

Aprimore o exemplo de login fornecido, implementando a regeneração do ID da sessão após o login para maior segurança.

  • Crie os arquivos login.php, dashboard.php e logout.php conforme os exemplos acima.
  • No login.php, após um login bem-sucedido, adicione session_regenerate_id(true);.
  • Teste o fluxo: faça login, navegue para o dashboard, faça logout.
  • (Opcional) Tente simular um ataque de Session Fixation: antes de logar, inspecione o cookie PHPSESSID (se for o padrão), anote-o, e depois de logar, verifique se ele mudou.

6. Resumo e Próximos Passos ✨

Nesta aula, exploramos as ferramentas essenciais para a persistência de dados em aplicações web PHP:

  • Cookies: Pequenos pedaços de dados armazenados no navegador do cliente, ideais para preferências do usuário e identificadores. Gerenciados com setcookie() e $_COOKIE.
  • Sessões: Mecanismo para armazenar dados no servidor, associados a um Session ID (geralmente enviado via cookie). Essenciais para gerenciamento de estado do usuário (login, carrinho). Gerenciados com session_start(), $_SESSION, session_unset() e session_destroy().

Lembre-se sempre das considerações de segurança ao trabalhar com cookies e sessões, como o uso de HTTPS, HttpOnly, Secure e a regeneração de IDs de sessão.

Próximos Passos:

  • Validação de Entrada: Sempre valide e filtre todas as entradas de usuário, seja para cookies, sessões ou formulários, para prevenir ataques como XSS e SQL Injection.
  • Armazenamento de Sessão Alternativo: Para aplicações de grande escala, você pode configurar o PHP para armazenar sessões em bancos de dados ou sistemas de cache (como Redis ou Memcached) em vez de arquivos.
  • Autenticação e Autorização Avançadas: Explore frameworks de autenticação que abstraem grande parte da complexidade e segurança do gerenciamento de sessões.
  • Criptografia: Para cookies que precisam armazenar dados um pouco mais sensíveis (mas ainda não senhas!), considere criptografar seu conteúdo antes de enviá-los.

Continue praticando e experimentando! A persistência de dados é um conceito fundamental para construir aplicações web dinâmicas e interativas. 💪

© 2025 Escola All Dev. Todos os direitos reservados.

Gerenciamento de sessões e cookies para persistência de dados - Fundamentos do PHP | escola.all.dev.br