Entendendo o CORS — Parte 1

CORS (Cross-Origin Resource Sharing) é uma especificação do W3C que, quando implementado pelo navegador, permite que um site acesse recursos de outro site mesmo estando em domínios diferentes.

Explicando um pouco melhor: os navegadores fazem uso de uma funcionalidade de segurança chamada Same-Origin Policy: um recurso de um site só pode ser chamado por outro site se os 2 sites estiverem sob o mesmo domínio (mesmo endereço, por ex.: meudominio.com.br). Isso limita a chamada de APIs REST por aplicações JS, por exemplo, hospedadas em servidores diferentes (front-end e back-end em camadas distintas). Isso porque o navegador considera recursos do mesmo domínio somente aqueles que usam o mesmo protocolo (http ou https), a mesma porta e o mesmo endereço (mesmo subdomínios, subdominio.meudominio.com.br, por exemplo, não são considerados seguros e não funcionam).

Antes do CORS, era possível contornar essa restrição criando algum tipo de componente que servisse de proxy para as chamadas externas. O uso do JSONP (JSON with padding) para APIs que dão suporte (pouco comum) também era uma saída. Contudo o JSONP é limitado somente a chamadas do tipo GET o que causa bastante transtorno para APIs baseadas em REST (que faz uso dos outros verbos POST, PUT e DELETE).

Com a implementação do CORS um domínio permite comunicação com outro de forma livre, independente do método da chamada (GET, POST, PUT ou DELETE) contanto que o domínio de destino tenha especificado esse tipo de comunicação.

Geralmente essa configuração é feita no lado da API e cada framework tem sua forma de configuração. A parte importante é a inclusão do Access-Control-Allow-Origin no header da reposta da API.

Então, em um cenário bem simples, sua aplicação JS cliente em dev.meudominio.com.br faz um request para a API (normalmente numa chamada AJAX) para o servidor api.meudominio.com.br. A resposta da API deve incluir no header da resposta o Access-Control-Allow-Origin: http://dev.meudominio.com.br deixando claro para o navegador que ele aceita requests originados somente desse domínio.

Então em um exemplo de chamada de dev.meudominio.com.br para api.meudominio.com.br/recurso.php, gera esse request header:

E a API deve gerar a resposta com o response header abaixo:

Se o conteúdo de Origin for idêntico ao de Access-Control-Allow-Origin a comunicação é permitida pelo navegador.

Em um cenário mais complexo, existem outros headers que precisam ser configurados na resposta. De novo, isso varia com os frameworks que estão sendo utilizados (cliente e servidor).

Na segunda parte desse artigo, vou tentar aprofundar um pouco mais e mostrar o uso de chamadas pre-flight e exemplos de algumas configurações que podem ser feitas em alguns frameworks.