Cookies são pequenos arquivos de texto armazenados no navegador do cliente, usados para manter estado entre requisições HTTP. Em PHP, o gerenciamento de cookies é feito principalmente através da função setcookie() e da superglobal $_COOKIE. Nesta aula, exploraremos como criar, ler, definir prazos de validade e aplicar medidas de segurança aos cookies.

Entender cookies é fundamental para desenvolver aplicações web que precisam de sessões, preferências do usuário ou rastreamento. Com as práticas corretas, você evita vulnerabilidades comuns como XSS e exposição de dados sensíveis.

setcookie

A função setcookie() é usada para definir um cookie que será enviado ao navegador junto com a resposta HTTP. Ela deve ser chamada antes de qualquer saída HTML (incluindo espaços em branco) porque os cabeçalhos HTTP precisam ser enviados antes do corpo.

A sintaxe básica é: setcookie(string $name, string $value = '', int $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool. O PHP 7.3+ também aceita um array associativo como terceiro parâmetro, simplificando a definição de opções.

// Exemplo simples de setcookie
setcookie('user_preference', 'dark_mode', time() + 3600, '/');
// O cookie expira em 1 hora, disponível em todo o site

Lendo cookies

Para ler um cookie enviado pelo navegador, usamos a superglobal $_COOKIE, que é um array associativo onde as chaves são os nomes dos cookies e os valores são seus conteúdos. É importante verificar se o cookie existe antes de acessá-lo para evitar warnings.

if (isset($_COOKIE['user_preference'])) {
    $preference = $_COOKIE['user_preference'];
    echo "Preferência do usuário: $preference";
} else {
    echo "Cookie não definido.";
}

Lembre-se de que os cookies podem ser manipulados pelo cliente, portanto nunca confie em dados de cookies para informações sensíveis sem validação.

Tempo de vida

O tempo de vida de um cookie é controlado pelo parâmetro expires (ou expires no array de opções). Ele deve ser um timestamp Unix (número de segundos desde 01/01/1970). Se definido como 0, o cookie expira quando o navegador é fechado (cookie de sessão). Para remover um cookie, defina o tempo de expiração para um valor no passado, por exemplo, time() - 3600.

// Cookie que expira em 7 dias
setcookie('remember_me', 'token', time() + 7 * 24 * 60 * 60, '/');

// Remover um cookie
setcookie('remember_me', '', time() - 3600, '/');

O caminho (path) e o domínio (domain) também influenciam onde o cookie é válido. Por padrão, o cookie é enviado apenas para o diretório atual e seus subdiretórios. Use '/' para disponibilizar em todo o domínio.

Segurança (HttpOnly, Secure)

Dois atributos importantes para segurança de cookies são HttpOnly e Secure. HttpOnly impede que o cookie seja acessado por JavaScript (mitigando ataques XSS). Secure faz com que o cookie só seja enviado em conexões HTTPS, protegendo contra interceptação em redes inseguras.

No PHP, você pode definir esses atributos diretamente nos parâmetros da função setcookie() ou usando o array de opções (PHP 7.3+). É recomendado sempre habilitar HttpOnly para cookies de sessão e Secure em produção com HTTPS.

// Forma tradicional (PHP < 7.3)
setcookie('session_id', $sessionId, 0, '/', '', true, true); // secure=true, httponly=true

// Forma moderna (PHP 7.3+)
setcookie('session_id', $sessionId, [
    'expires' => 0,
    'path' => '/',
    'domain' => '',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict' // opcional: protege contra CSRF
]);

O atributo SameSite (Strict, Lax, None) também é importante para prevenir ataques CSRF. Em PHP 7.3+, pode ser incluído no array de opções. Sempre prefira SameSite=Lax ou Strict quando possível.

Boas práticas

  • Sempre defina HttpOnly e Secure em cookies de sessão.
  • Não armazene senhas ou dados sensíveis em cookies; use sessões no servidor.
  • Valide e sanitize dados de cookies antes de usar.
  • Defina um caminho específico se o cookie não for necessário em todo o site.
  • Use tempos de expiração razoáveis e permita que o usuário limpe os cookies.

Referências

Exercícios

  1. Crie um cookie chamado 'theme' com valor 'light' que expire em 1 hora e esteja disponível em todo o site.

    ✓ Resposta:
    setcookie('theme', 'light', time() + 3600, '/');
  2. Leia o cookie 'theme' e exiba seu valor. Se não existir, exiba 'Cookie não definido'.

    ✓ Resposta:
    if (isset($_COOKIE['theme'])) {
        echo $_COOKIE['theme'];
    } else {
        echo 'Cookie não definido';
    }
  3. Remova o cookie 'theme' definindo sua expiração para o passado.

    ✓ Resposta:
    setcookie('theme', '', time() - 3600, '/');
  4. Crie um cookie 'session_token' com HttpOnly e Secure ativados, válido para todo o site, sem expiração (cookie de sessão). Use a sintaxe moderna (array de opções).

    ✓ Resposta:
    setcookie('session_token', 'abc123', [
        'expires' => 0,
        'path' => '/',
        'secure' => true,
        'httponly' => true,
        'samesite' => 'Strict'
    ]);
  5. Escreva um script que verifique se o cookie 'user_logged' existe e, se sim, exiba 'Bem-vindo de volta!', caso contrário, defina o cookie com valor '1' e exiba 'Cookie definido'.

    ✓ Resposta:
    if (isset($_COOKIE['user_logged'])) {
        echo 'Bem-vindo de volta!';
    } else {
        setcookie('user_logged', '1', time() + 86400, '/'); // 1 dia
        echo 'Cookie definido';
    }