FNSP Web Page

CORS: o erro que toda a gente já viu e quase ninguém explica

É provavelmente a mensagem mais copiada para o Google em toda a história do desenvolvimento web:

Access to fetch at 'https://api.exemplo.pt/dados' from origin
'https://meusite.pt' has been blocked by CORS policy

E a reação mais comum é a errada: procurar como "desligar o CORS" no browser.

1. Quem bloqueia é o browser, não o servidor

A regra de origem única existe para proteger quem visita. Sem ela, um site qualquer aberto noutro separador podia fazer pedidos ao seu banco usando os cookies que já lá estão, e ler a resposta.

O CORS é a forma de um servidor dizer "com este outro sítio, pode". Repare no detalhe que muda tudo: o pedido chegou ao servidor e foi executado. O que o browser bloqueou foi o JavaScript da página ler a resposta.

2. A autorização é um cabeçalho

// No servidor
res.setHeader('Access-Control-Allow-Origin', 'https://meusite.pt');

É por isso que não há nada a fazer do lado do cliente: quem tem de mudar é o servidor a que se está a pedir. Se ele não for seu, a solução é pedir a partir do seu servidor, que não tem browser nenhum a impor regras.

3. O pedido a mais: o preflight

Para pedidos que não sejam simples — um PUT, um DELETE, um cabeçalho próprio, ou Content-Type: application/json — o browser manda primeiro um OPTIONS a perguntar se pode:

OPTIONS /dados
Origin: https://meusite.pt
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type

# Resposta
Access-Control-Allow-Origin: https://meusite.pt
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: content-type
Access-Control-Max-Age: 86400

O Max-Age diz ao browser quanto tempo pode guardar essa autorização. Sem ele, é um pedido a mais por cada pedido a sério.

4. A armadilha dos cookies

Para enviar cookies ou cabeçalhos de autenticação, o servidor tem de responder com Access-Control-Allow-Credentials: true — e nesse caso o asterisco deixa de ser válido. Tem de dizer a origem exata.

// Isto o browser recusa, e com razão
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

É uma proteção contra o caso em que alguém copia um "aceita tudo" de um exemplo e o põe num serviço com sessões.

Comentários

Ainda ninguém comentou este artigo.

Voltar ao blog

Gostávamos de saber quantas pessoas visitam o site, com o Google Analytics. Sem a sua autorização não corre nada. Política de Privacidade.