Quando tentamos conectar a nossa API a uma aplicação Front-end (como React, Angular, Vue ou até mesmo um arquivo HTML simples rodando localmente), o navegador costuma bloquear a comunicação por motivos de segurança, gerando um erro clássico no console. Hoje vamos entender o que é o CORS e como resolvê-lo de forma nativa no Go.
CORS significa Cross-Origin Resource Sharing (Compartilhamento de Recursos de Origem Cruzada). Trata-se de um mecanismo de segurança dos navegadores que impede que um site hospedado em uma origem (ex: http://localhost:5500) acesse os dados de uma API que está rodando em outra origem diferente (ex: http://localhost:8080), a menos que a API diga explicitamente que confia e permite esse acesso.
Para liberar o acesso, precisamos criar uma engrenagem que intercepta todas as requisições que chegam e adiciona cabeçalhos especiais de segurança informando que a nossa API está aberta para receber conexões externas. Chamamos essa engrenagem de Middleware.
Adicione a função abaixo no seu arquivo main.go (pode ser logo acima ou abaixo da sua função main). Ela interceptará os pedidos, injetará as permissões necessárias para o navegador e tratará de forma segura as requisições do tipo OPTIONS (conhecidas como Preflight):
// Middleware de CORS adaptado para o Gin
func corsMiddleware() gin.HandlerFunc {
// Retorno
return func(c *gin.Context) {
// Configurações
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
// Options
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
return
}
// Next
c.Next()
}
}
Agora precisamos referenciar essa função, use o comando r.Use(corsMiddleware()) abaixo do roteador. Abaixo compartilho a estrutura atualizada da função principal:
// Função principal
func main() {
// Roteador
r := gin.Default()
// Configurar CORS
r.Use(corsMiddleware()) // <- Adicionada essa linha
// Rotas
r.GET("/", helloWorld)
r.GET("/produtos", listarProdutos)
r.POST("/produtos", cadastrarProduto)
r.PUT("/produtos/:codigo", alterarProduto)
r.DELETE("/produtos/:codigo", removerProduto)
// Configurar o servidor
r.Run(":8080")
}
Para testar se o CORS foi resolvido com sucesso, crie um arquivo HTML local no seu computador para simular um sistema Front-end realizando uma busca de dados (fetch) na sua API e exibindo os alunos cadastrados no terminal do navegador através de uma tabela.
Para facilitar os seus testes, você pode fazer o download do arquivo HTML pronto clicando no link abaixo:
(Caso prefira criar o arquivo manualmente, utilize a estrutura de código abaixo):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Testar API</title>
<!-- Script -->
<script>
// Realizar requisição para o nosso endpoint de listagem
fetch("http://localhost:8080/produtos")
.then(retornoAPI => retornoAPI.json())
.then(produtos => console.table(produtos)) // Exibe os dados formatados em tabela no console do navegador
.catch(erro => console.error("Erro ao conectar na API:", erro))
</script>
<h1>Abra o Console do Navegador (F12) para ver o resultado do teste!</h1>