Compartilhar recursos entre origens com segurança
A política de mesma origem do navegador bloqueia a leitura de um recurso de uma 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, recuperando dados JSON de um domínio diferente ou carregando 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 deles. Os desenvolvedores já usaram soluções alternativas, como o
JSONP.
O compartilhamento de recursos entre origens (CORS) corrige esse problema de maneira padronizada. A ativação do CORS permite que o servidor informe ao navegador que pode usar uma origem adicional.
Como funciona uma solicitação de recurso na Web?
Um navegador e um servidor podem trocar dados pela rede usando o protocolo de transferência de hipertexto (HTTP). O HTTP define as regras de comunicação entre o solicitante e o respondente, incluindo quais informações são necessárias para acessar 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 um cabeçalho e um corpo.
Cabeçalho
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. O cabeçalho de solicitação e o cabeçalho de resposta contêm informações diferentes.
Exemplo de cabeçalho de solicitação
Accept: text/html
Cookie: Version=1
Esse cabeçalho equivale a dizer “Quero receber HTML em resposta. Aqui está um cookie que tenho."
Exemplo de cabeçalho de resposta
Content-Encoding: gzip
Cache-Control: no-store
Esse cabeçalho equivale a dizer "Os dados nessa resposta são codificados com gzip. Não armazene em cache."
Corpo
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 uma origem diferente, o servidor que fornece o recurso informa ao navegador que a origem que envia a solicitação pode acessar o recurso. O navegador se lembra disso e permite o compartilhamento de recursos entre origens para esse recurso.
Etapa 1: solicitação do cliente (navegador)
Quando o navegador faz uma solicitação de diferentes origens, ele adiciona um cabeçalho Origin
com a origem atual (esquema, host e porta).
Etapa 2: resposta do servidor
Quando um servidor detecta esse cabeçalho e quer permitir o acesso, ele adiciona um
cabeçalho Access-Control-Allow-Origin
à resposta especificando a origem
de solicitação (ou *
para permitir qualquer origem).
Etapa 3: o navegador recebe uma resposta
Quando o navegador encontra essa resposta com um cabeçalho
Access-Control-Allow-Origin
adequado, ele compartilha os dados de resposta com o
site do cliente.
Compartilhar credenciais com 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, adicione cabeçalhos adicionais à solicitação e à resposta.
Solicitação
Adicione credentials: 'include'
às opções de busca, como no exemplo a seguir.
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
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 simulada ao início da cadeia de solicitações.
A especificação CORS define uma solicitação complexa da seguinte maneira:
- 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
ouContent-Language
. - Uma solicitação que tem um cabeçalho
Content-Type
diferente deapplication/x-www-form-urlencoded
,multipart/form-data
outext/plain
.
Os navegadores criam automaticamente todas as solicitações de pré-voo necessárias e as enviam
antes da mensagem de solicitação real. A solicitação de simulação é uma solicitação OPTIONS
,
como no exemplo abaixo:
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 pré-voo com informações sobre os métodos aceitos pelo aplicativo 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 da simulação. Isso permite que o
cliente envie várias solicitações complexas sem precisar repetir a solicitação
de simulação.