Compartilhamento de recursos entre origens (CORS, na sigla em inglês)

Compartilhe recursos de origem cruzada com segurança

Mariko Kosaka

A política de mesma origem do navegador bloqueia a leitura de um recurso de origem diferente. Esse mecanismo impede que sites maliciosos leiam os dados de outros sites, mas também impede usos legítimos.

Os apps da Web modernos geralmente querem receber recursos de uma origem diferente, por exemplo, recuperar dados JSON de um domínio diferente ou carregar imagens de outro site em um elemento <canvas>. Eles podem ser recursos públicos que precisam estar disponíveis para qualquer pessoa ler, mas a política de mesma origem bloqueia o uso. Historicamente, os desenvolvedores têm usado soluções alternativas, como o JSONP.

O Compartilhamento de recursos entre origens (CORS) corrige esse problema de maneira padronizada. Ativar o CORS permite que o servidor informe ao navegador que ele pode usar uma origem adicional.

Como funciona uma solicitação de recurso na Web?

solicitação e resposta
Ilustração da solicitação do cliente e da resposta do servidor.

Um navegador e um servidor podem trocar dados pela rede usando o Hypertext Transfer Protocol (HTTP). O HTTP define as regras de comunicação entre o solicitante e o responsável pela resposta, incluindo quais informações são necessárias para receber um recurso.

O cabeçalho HTTP negocia a troca de mensagens entre o cliente e o servidor e é usado para determinar o acesso. A solicitação do navegador e a mensagem de resposta do servidor são divididas em cabeçalho e corpo.

Informações sobre a mensagem, como o tipo ou a codificação dela. Um cabeçalho pode incluir uma variedade de informações expressas como pares de chave-valor. Os cabeçalhos da solicitação e da resposta contêm informações diferentes.

Exemplo de cabeçalho de solicitação

Accept: text/html
Cookie: Version=1

Esse cabeçalho é equivalente a dizer "Quero receber HTML em resposta. Aqui está um biscoito que tenho."

Exemplo de cabeçalho de resposta

Content-Encoding: gzip
Cache-Control: no-store

Esse cabeçalho é equivalente a dizer "Os dados nesta resposta são codificados com gzip. Não armazene isso em cache."

Body

A mensagem em si. Pode ser texto simples, um binário de imagem, JSON, HTML ou muitos outros formatos.

Como funciona o CORS?

A política de mesma origem instrui o navegador a bloquear solicitações de origem cruzada. Quando você precisa de um recurso público de origem diferente, o servidor que fornece recursos informa ao navegador que a origem que envia a solicitação pode acessar o recurso. O navegador lembra disso e permite o compartilhamento de recursos entre origens para o recurso.

Etapa 1: solicitação do cliente (navegador)

Quando o navegador faz uma solicitação de origem cruzada, ele adiciona um cabeçalho Origin com a origem atual (esquema, host e porta).

Etapa 2: resposta do servidor

Quando um servidor vê esse cabeçalho e quer permitir o acesso, ele adiciona um cabeçalho Access-Control-Allow-Origin à resposta especificando a origem da solicitação (ou * para permitir qualquer origem).

Etapa 3: o navegador recebe resposta

Quando o navegador vê essa resposta com um cabeçalho Access-Control-Allow-Origin apropriado, ele compartilha os dados de resposta com o site do cliente.

Compartilhar credenciais com o CORS

Por motivos de privacidade, o CORS normalmente é usado para solicitações anônimas, em que o solicitante não é identificado. Se você quiser enviar cookies ao usar o CORS, que pode identificar o remetente, será necessário adicionar outros cabeçalhos à solicitação e à resposta.

Solicitação

Adicione credentials: 'include' às opções de busca, como no exemplo abaixo. Isso inclui o cookie com a solicitação da seguinte maneira:

fetch('https://example.com', {
  mode: 'cors',
  credentials: 'include'
})

Resposta

Access-Control-Allow-Origin precisa ser definido como uma origem específica (sem caractere curinga usando *) e Access-Control-Allow-Credentials precisa ser definido como true.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

Solicitações de simulação para chamadas HTTP complexas

Quando um app da Web faz uma solicitação HTTP complexa, o navegador adiciona uma solicitação de simulação ao início da cadeia de solicitações.

A especificação do CORS define uma solicitação complexa da seguinte forma:

  • Uma solicitação que usa métodos diferentes de GET, POST ou HEAD.
  • Uma solicitação que inclui cabeçalhos diferentes de Accept, Accept-Language ou Content-Language.
  • Uma solicitação com um cabeçalho Content-Type diferente de application/x-www-form-urlencoded, multipart/form-data ou text/plain.

Os navegadores criam automaticamente todas as solicitações de simulação necessárias e as enviam antes da mensagem de solicitação real. A solicitação de simulação é uma solicitação OPTIONS como o exemplo a seguir:

OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE

No lado do servidor, o app que recebe a solicitação responde à solicitação de simulação com informações sobre os métodos que o aplicativo aceita dessa origem:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

A resposta do servidor também pode incluir um cabeçalho Access-Control-Max-Age para especificar a duração em segundos para armazenar em cache os resultados de simulação. Isso permite que o cliente envie várias solicitações complexas sem precisar repetir a solicitação de simulação.