Cookies e Sessão - conceitos e utilização com PHP
Published: 2023-07-28 02:18:39

## Tópicos
&nbsp;1. [Introdução](#introdu%C3%A7%C3%A3o)
&nbsp;2. [Cookies](#cookies)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1. [Conceito](#conceito)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2. [Manipulação](#manipula%C3%A7%C3%A3o)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. [Criação de Cookies](#cria%C3%A7%C3%A3o-de-cookies)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. [Leitura de Cookies](#leitura-de-cookies)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c. [Exclusão de Cookies](#exclus%C3%A3o-de-cookies)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.3. [Exemplo em PHP](#exemplo-em-php)
&nbsp;3. [Sessões](#sess%C3%B5es)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1. [Conceito](#conceito)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2. [Manipulação](#manipula%C3%A7%C3%A3o)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a. [Criação de Sessões](#cria%C3%A7%C3%A3o-de-sess%C3%B5es)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b. [Leitura de Sessões](#leitura-de-sess%C3%B5es)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c. [Exclusão de Sessões](#exclus%C3%A3o-de-sess%C3%B5es)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.3. [Exemplo em PHP](#exemplo-em-php)
&nbsp;4. [Conclusão](#conclus%C3%A3o)

## Introdução

A palavra "sessão" em português é curiosa, pois tem a mesma sonoridade que cessão, seção e é muito similar à secção, cujos significados são completamente distintos. No contexto de Aplicações Web, o termo sessão representa um espaço de tempo durante o qual uma atividade específica é realizada, como a interação do usuário com um ambiente de web-email ou uma rede social.

Entretanto, o protocolo HTTP utilizado em Aplicações Web é stateless, o que significa que ele não mantém informações de estado ou identificação sobre quem está fazendo a requisição. Em aplicações mais complexas, essas informações são essenciais para personalizar a experiência do usuário e fornecer conteúdo relevante. Por exemplo, em uma rede social, é necessário saber quem está fazendo a requisição para gerar um feed personalizado para aquele usuário. É neste contexto que entram os Cookies e as Sessões.

## Cookies

### Conceito

Cookies são pequenos arquivos de texto armazenados no navegador do usuário. Eles foram criados para resolver o desafio da falta de estado (*statelessness*) no protocolo HTTP. Quando o servidor envia uma resposta para o navegador com o intuito de criar um cookie, o navegador armazena esses dados e, em seguida, envia-os de volta para o servidor em todas as requisições subsequentes relacionadas ao mesmo domínio. Dessa forma, os cookies permitem que as aplicações web mantenham informações sobre o usuário em requisições sucessivas ou até mesmo após ele navegar para outras páginas ou fechar o navegador.

### Manipulação

A manipulação de cookies envolve três principais ações: criação, leitura e exclusão.

#### Criação de Cookies

Para criar um cookie, após uma requisição, o servidor envia um cabeçalho HTTP com a resposta que contém os dados do cookie que deseja armazenar no navegador do usuário. Esse cabeçalho geralmente é chamado de "Set-Cookie". Ele pode conter informações como nome, valor, data de expiração, domínio e caminho. Esses dados serão armazenados no navegador do usuário e enviados de volta para o servidor em todas as requisições futuras relacionadas ao mesmo domínio.

#### Leitura de Cookies

Quando o usuário navega para outras páginas ou faz novas requisições ao mesmo domínio, o navegador envia automaticamente os cookies relacionados a esse domínio no cabeçalho da requisição HTTP. O servidor pode então ler esses cookies e utilizar as informações armazenadas para personalizar a experiência do usuário ou fornecer conteúdo relevante.

#### Exclusão de Cookies

Para excluir um cookie, o servidor envia uma resposta HTTP com um cabeçalho "Set-Cookie" que instrui o navegador a remover o cookie do armazenamento local. Para fazer isso, geralmente é definida uma data de expiração passada, o que faz com que o cookie seja considerado inválido e, portanto, excluído pelo navegador.

### Exemplo em PHP

Considere os seguintes códigos em PHP:

```php
<!-- set_cookie.php -->
<?php
// Criando um cookie com o nome "usuario" e o valor "joao123"
setcookie("usuario", "joao123", time() + (86400 * 30), "/");

// Setando o código de resposta para 302 - Found
http_response_code(302);

// Adicionando o cabeçalho 'Location', que informará ao browser para onde o usuário deve ser redirecionado (qual o próximo request que deve ser feito)
header('Location: /');
```

```php
<!-- index.php -->
<?php
// Verificando se o cookie "usuario" está definido
if(isset($_COOKIE['usuario'])) {
    // Obtendo o valor do cookie
    $usuario = $_COOKIE['usuario'];
    echo "Bem-vindo de volta, $usuario!";
} else {
    echo "Olá, visitante!"; // Caso o cookie não esteja definido
}
?>
```


Suponha que estes dois arquivos estão num diretório e que este é o diretório raiz de um servidor embutido do PHP escutando na porta `8080`. Neste caso, quando o usuário fizer a primeira requisição para `http://localhost:8080`, o arquivo `index.php` será executado, e considerando o cenário que não há nenhum cookie salvo (o que acontece, por exemplo, quando se abre uma página usando a navegação anônima), a condição do `if` será falsa e será respondido "Olá, visitante". 

Agora, considere que o usuário digitou em sua barra de endereço `http://localhost:8080/set_cookie.php`. Quando a requisição chegar no servidor, o código do arquivo `set_cookie.php` será executado e irá adicionar o cabeçalho "Set-Cookie" (através da função [`setcookie()`](https://www.php.net/manual/pt_BR/function.setcookie.php), o cabeçalho "Location" utilizando a função [`header()`](https://www.php.net/manual/pt_BR/function.header.php) e alterar o código de resposta para 302 (*Found*). Com isso, o navegador fará duas coisas:
1. Adicionar o cookie "usuario" com o valor "joao123", que expirará em 30 dias (86400 == um dia).
2. Com o código de resposta de redirecionamento, fará uma nova requisição para a URI contida no cabeçalho "Location" (`/`).

Nesta nova requisição o cookie `usuario=joao123` será adicionado como um cabeçalho extra no pacote HTTP, já que sua data de expiração é posterior à data atual. Isso fará com que o código do `if` seja executado, já que nesta requisição há um cookie chamado "usuario". Note que o PHP utiliza a variável superglobal `$_COOKIE`, que se comporta como um array associativo de forma similar às variáveis `$_GET` e `$_POST`, acessando dados provenientes do pacote HTTP da requisição. Para mais informações, você pode ler a documentação [$_COOKIE no manual do PHP](https://www.php.net/manual/pt_BR/reserved.variables.cookies).

Para mais informações sobre cookies, você pode acessar a página de [Cookies HTTP no MDN](https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Cookies)

## Sessões

### Conceito

As sessões são uma abstração mais amigável e segura para gerenciar informações de estado do que os cookies. Enquanto os cookies são armazenados no lado do cliente, as sessões são armazenadas no servidor. Um cookie é usado para rastrear a sessão do usuário, mas os dados da sessão em si são armazenados no servidor, não no cookie.

### Manipulação

A manipulação de sessões também envolve três ações principais: criação, leitura e exclusão.

#### Criação de Sessões

Ao criar uma sessão, o servidor gera um identificador exclusivo chamado "*session ID*" e o envia para o navegador do usuário por meio de um cookie (geralmente chamado de "PHPSESSID" em aplicações PHP). Esse cookie contém o ID da sessão, que é usado para identificar a sessão no servidor.

#### Leitura de Sessões

Quando o usuário faz uma requisição ao servidor, o navegador envia o cookie contendo o *session ID* associado à sessão atual. O servidor usa esse *session ID* para recuperar os dados da sessão correspondentes armazenados em seu sistema. Isso permite que o servidor identifique o usuário e acesse as informações da sessão associadas. Em PHP isso é feito através da combinação da função `session_start()` e da variável superglobal `$_SESSION`, conforme será exemplificado a seguir.

#### Exclusão de Sessões

A exclusão de uma sessão geralmente ocorre quando o usuário encerra sua interação com a aplicação ou quando a sessão expira por inatividade (ou seja, quando o cookie contendo o *session ID* expira). Nesse momento, o servidor pode limpar os dados da sessão armazenados no servidor e instruir o navegador a excluir o cookie contendo o *session ID*, invalidando assim a sessão atual. Em PHP isso pode ser feito através da função [`session_destroy()`](https://www.php.net/manual/pt_BR/function.session-destroy.php).

### Exemplo em PHP

Vamos agora reescrever o código do exemplo anterior utilizando uma sessão ao invés do cookie para armazenar o nome do usuário. Para isso, considere os seguintes códigos:

```php
<!-- set_session.php -->
<?php
// Iniciando a sessão
session_start();

// Armazenando dados na sessão
$_SESSION['usuario'] = "maria123";

http_response_code(302);
header('Location: /');
```

```php
<!-- index.php -->
<?php
// Iniciando a sessão
session_start();

// Verificando se o valor 'usuario' está definido na sessão
if(isset($_SESSION['usuario'])) {
    // Obtendo e exibindo o valor armazenado
    $usuario = $_SESSION['usuario'];
    echo "Bem-vind@, $usuario!";
} else {
    echo "Olá, visitante!"; // Caso o valor 'nome' não esteja definido na sessão
}
?>
```


Neste exemplo, considerando o mesmo ambiente do exemplo anterior, quando a primeira requisição for feita para `http://localhost:8080` a função [`session_start()`](https://www.php.net/manual/pt_BR/function.session-start) irá verificar que não existe um cookie contendo um *session ID*. Com isso, ela irá criar uma nova sessão, com seu *session ID*, e adicioná-lo no cabeçalho da resposta ao cliente. Ainda assim, a condição do `if` será falsa, pois a sessão (representada no PHP por um array associativo, guardado na variável superglobal `$_SESSION`) está vazia. Assim, a resposta será "Olá, visitante!", da mesma forma que antes, mas com uma diferença: desta vez há um cookie sendo setado automaticamente.

Quando o usuário acessar então `http://localhost:8080/set_session.php`, a função `session_start()` irá verificar que já existe um cookie de sessão (`PHPSESSID`) e irá carregar na superglobal `$_SESSION` os dados correspondentes (mas lembre-se que a sessão ainda está vazia). Logo a seguir, o código adiciona no índice "usuario" da sessão o valor "maria123", e redireciona o cliente para a index, da mesma forma que no exemplo anterior.

Agora, fazendo uma nova requisição para a URI `/`, a execução de `session_start()` em `index.php` irá fazer o mesmo que antes – verificar que existe um cookie de sessão e carregar a superglobal `$_SESSION` com os dados. Neste momento, entretando, o array carregado tem no índice "usuario" o valor "maria123". Com isso, a condição do `if` será verdadeira e o código prosseguirá normalmente.

A grade diferença aqui é que, enquanto no exemplo anterior o valor de "usuario" está salvo no cliente, neste exemplo este valor está salvo no servidor. Lembre-se que os dados armazenados no cliente são passíveis de leitura e modificação por parte dos usuários, o que significa que, no exemplo anterior, um usuário malicioso poderia deliberadamente trocar seu nome de usuário, mesmo tendo sido setado pelo servidor, já que este dado está salvo em um cookie. Neste segundo exemplo, o usuário apenas tem acesso a um *session ID*, que indicará ao servidor onde, no seu lado, os dados estão salvos. Dessa forma, mesmo um usuário malicioso não é capaz de modificar o que está no servidor, podendo no máximo fazer um [ataque de roubo de sessão](https://owasp.org/www-community/attacks/Session_hijacking_attack).

## Conclusão

Cookies e sessões são fundamentais para permitir que as Aplicações Web mantenham informações de estado e identificação dos usuários. Enquanto os cookies são armazenados no navegador do usuário e permitem a personalização da experiência do usuário em várias páginas, as sessões oferecem uma abordagem mais segura, armazenando os dados do usuário no servidor. A escolha entre cookies e sessões depende das necessidades específicas da aplicação e do nível de segurança desejado.