Português

Desvende os segredos do CORS (Compartilhamento de Recursos de Origem Cruzada) e aprenda como habilitar solicitações entre domínios com segurança em suas aplicações web. Este guia abrangente cobre tudo, desde o básico até configurações avançadas, garantindo uma comunicação fluida e segura entre diferentes origens.

Desmistificando o CORS: Um Guia Abrangente sobre o Compartilhamento de Recursos de Origem Cruzada

Na web interconectada de hoje, as aplicações frequentemente precisam acessar recursos de diferentes origens. É aqui que o Compartilhamento de Recursos de Origem Cruzada (CORS) entra em cena. O CORS é um mecanismo de segurança crucial que rege como os navegadores da web lidam com requisições de uma origem (domínio, protocolo e porta) para uma origem diferente. Entender o CORS é essencial para todo desenvolvedor web construir aplicações seguras e funcionais.

O que é a Política de Mesma Origem?

Antes de mergulhar no CORS, é importante entender a Política de Mesma Origem (SOP - Same-Origin Policy). A SOP é um mecanismo de segurança fundamental implementado nos navegadores da web. Seu propósito é impedir que scripts maliciosos em um site acessem dados sensíveis em outro site. Uma origem é definida pela combinação do protocolo (ex: HTTP ou HTTPS), o domínio (ex: example.com) e o número da porta (ex: 80 ou 443). Duas URLs são consideradas de mesma origem se compartilharem o mesmo protocolo, domínio e porta.

Exemplo:

A SOP restringe o acesso de scripts a recursos de uma origem diferente, a menos que medidas específicas, como o CORS, estejam em vigor para permitir isso.

Por que o CORS é Necessário?

Embora a Política de Mesma Origem seja vital para a segurança, ela também pode ser restritiva. Muitas aplicações web modernas dependem da busca de dados de diferentes servidores, como APIs ou redes de entrega de conteúdo (CDNs). O CORS fornece uma maneira controlada de flexibilizar a SOP e permitir requisições legítimas de origem cruzada, mantendo a segurança.

Considere um cenário em que uma aplicação web hospedada em http://example.com precisa buscar dados de um servidor de API hospedado em http://api.example.net. Sem o CORS, o navegador bloquearia essa requisição devido à SOP. O CORS permite que o servidor de API especifique explicitamente quais origens têm permissão para acessar seus recursos, permitindo que a aplicação web funcione corretamente.

Como o CORS Funciona: O Básico

O CORS funciona através de uma série de cabeçalhos HTTP trocados entre o cliente (navegador) e o servidor. O servidor usa esses cabeçalhos para informar ao navegador se ele tem permissão para acessar o recurso solicitado. O principal cabeçalho HTTP envolvido é o Access-Control-Allow-Origin.

Cenário 1: Requisição Simples

Uma "requisição simples" é uma requisição GET, HEAD ou POST que atende a critérios específicos (por exemplo, o cabeçalho Content-Type é um de application/x-www-form-urlencoded, multipart/form-data ou text/plain). Nesse caso, o navegador envia a requisição diretamente ao servidor, e o servidor responde com o cabeçalho Access-Control-Allow-Origin.

Requisição do Cliente (de http://example.com):

GET /data HTTP/1.1
Host: api.example.net
Origin: http://example.com

Resposta do Servidor (de http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "data": "Alguns dados do servidor"
}

Neste exemplo, o servidor responde com Access-Control-Allow-Origin: http://example.com, indicando que requisições de http://example.com são permitidas. Se a origem na requisição não corresponder ao valor no cabeçalho Access-Control-Allow-Origin (ou se o cabeçalho não estiver presente), o navegador bloqueará a resposta e impedirá que o script do lado do cliente acesse os dados.

Cenário 2: Requisição Preflight (para Requisições Complexas)

Para requisições mais complexas, como aquelas que usam métodos HTTP como PUT, DELETE, ou aquelas com cabeçalhos personalizados, o navegador realiza uma requisição "preflight" usando o método HTTP OPTIONS. Essa requisição preflight pede permissão ao servidor antes de enviar a requisição real. O servidor responde com cabeçalhos que especificam quais métodos, cabeçalhos e origens são permitidos.

Requisição Preflight do Cliente (de http://example.com):

OPTIONS /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

Resposta do Servidor (de http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header, Content-Type
Access-Control-Max-Age: 3600

Explicação dos Cabeçalhos:

Se a resposta preflight do servidor indicar que a requisição é permitida, o navegador prossegue com a requisição real. Caso contrário, o navegador bloqueia a requisição.

Requisição Real do Cliente (de http://example.com):

PUT /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
X-Custom-Header: some-value
Content-Type: application/json

{
  "data": "Alguns dados a serem atualizados"
}

Resposta do Servidor (de http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "status": "Dados atualizados com sucesso"
}

Cabeçalhos CORS Comuns

Aqui está uma análise dos principais cabeçalhos CORS que você precisa entender:

CORS em Diferentes Linguagens de Servidor

A implementação do CORS geralmente envolve a configuração de sua aplicação do lado do servidor para enviar os cabeçalhos CORS apropriados. Aqui estão exemplos de como fazer isso em várias linguagens e frameworks:

Node.js com Express

Você pode usar o pacote de middleware cors:

const express = require('express');
const cors = require('cors');

const app = express();

// Habilita o CORS para todas as origens (USE COM CAUTELA EM PRODUÇÃO)
app.use(cors());

// Alternativamente, configure o CORS para origens específicas
// app.use(cors({
//   origin: 'http://example.com'
// }));

app.get('/data', (req, res) => {
  res.json({ message: 'Isto está com CORS habilitado para todas as origens!' });
});

app.listen(3000, () => {
  console.log('Servidor rodando na porta 3000');
});

Python com Flask

Você pode usar a extensão Flask-CORS:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Alternativamente, configure o CORS para origens específicas
# CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})

@app.route("/data")
def hello():
    return {"message": "Isto está com CORS habilitado para todas as origens!"}

if __name__ == '__main__':
    app.run(debug=True)

Java com Spring Boot

Você pode configurar o CORS em sua aplicação Spring Boot usando anotações ou classes de configuração:

Usando Anotações:

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin(origins = "http://example.com") // Permite requisições de http://example.com
public class DataController {

    @GetMapping("/data")
    public String getData() {
        return "Isto está com CORS habilitado para http://example.com!";
    }
}

Usando Configuração:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/data")
                .allowedOrigins("http://example.com") // Permite requisições de http://example.com
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

PHP

 "Isto está com CORS habilitado para http://example.com!");
echo json_encode($data);
?>

CORS e Considerações de Segurança

Embora o CORS habilite requisições de origem cruzada, é crucial implementá-lo com segurança. Aqui estão algumas considerações importantes:

Solucionando Problemas de CORS

Problemas de CORS podem ser frustrantes de depurar. Aqui estão alguns problemas comuns e como resolvê-los:

Ferramentas de Depuração:

Cenários Avançados de CORS

Embora os conceitos básicos do CORS sejam relativamente diretos, existem alguns cenários mais avançados a serem considerados:

Melhores Práticas de CORS

Para garantir uma implementação segura e eficiente do CORS, siga estas melhores práticas:

Conclusão

O CORS é um mecanismo de segurança crítico que permite requisições controladas de origem cruzada em aplicações web. Entender como o CORS funciona e como configurá-lo adequadamente é essencial para todo desenvolvedor web. Seguindo as diretrizes e melhores práticas descritas neste guia abrangente, você pode construir aplicações web seguras e funcionais que interagem perfeitamente com recursos de diferentes origens.

Lembre-se de sempre priorizar a segurança e evitar o uso de configurações de CORS excessivamente permissivas. Ao considerar cuidadosamente as implicações de segurança de suas configurações de CORS, você pode proteger suas aplicações e dados de acesso não autorizado.

Esperamos que este guia tenha ajudado a desmistificar o CORS. Bom desenvolvimento!

Desmistificando o CORS: Um Guia Abrangente sobre o Compartilhamento de Recursos de Origem Cruzada | MLOG