Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Quem nunca tentou integrar um front-end com um back-end e recebeu um erro parecido com esse aqui:
Access to XMLHttpRequest at ‘http://localhost:8080/api/v1/resource’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
Ou ainda recebendo como resposta HTTP 403, de um recurso que você tem certeza que tem permissão para acessar.
Bom se isso está acontecendo com você, saiba que você está sendo bloqueado pela politica de CORS da api backend, e se o backend está escrito usando o framework Spring Boot, veio ao lugar certo vamos ensinar você a ajustar isso e parar de receber esse erro.
CORS na verdade quer dizer Cross-Origin Resource Sharing é um mecanismo que permite restringir recursos de um domínio, que serão recuperados por outro domínio.
Basicamente funciona da seguinte forma os recursos de um domínio só podem ser recuperados se a chamada vier do mesmo domínio em caso de a chamada vir de outro domínio essa chamada é bloqueada evitando que os recursos sejam recuperados.
Basicamente o funcionamento do CORS está restritos aos browsers, se você está tendo um erro com a chamada, e tentar fazer a mesma chamada por um software de requisições REST como Postman ou o Insominia, vai perceber que esse erro não acontece.
Isso porque o browser (Navegador de internet) é quem é responsável por fazer a verificação de Cross-Origin.
Por padrão o Spring Boot, vem definido para aceitar requisições apenas do próprio domínio, para configurar o recebimento de outros domínios, basta fazer a seguinte configuração:
package com.artefatox.example.controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
@CrossOrigin(origins = "*")
@GetMapping("/greeting")
public String greeting(@RequestParam("name") String name) {
return "Olá " + name;
}
}
JavaNessa configuração básica usamos a annotation @CrossOrigin
e na propriedade origins
que recebe um Array de strings podemos definir os domínios permitidos nesse endpoint.
Note também que essa configuração vai afetar apenas esse endpoint, e da forma que configuramos estamos permitindo aceitar requisições de qualquer outro domínio, pois estamos usando o coringa *.
Dependendo de como sua aplicação vai ser exposta e o nível de acesso que você pretende delimitar para ela é interessante colocar a url do próprio domínio ao invés do coringa *.
Para aplicar mais de um domínio nessa configuração pode-se usar o exemplo abaixo:
package com.artefatox.example.controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
@CrossOrigin(origins = { "example1.com", "example2.com" })
@GetMapping("/greeting")
public String greeting(@RequestParam("name") String name) {
return "Olá " + name;
}
}
JavaMas então se eu tiver 10 endpoints vou precisar marcar todos com a configuração de CORS? Bom a resposta é não, é possível em aplicações Spring Boot configurar de forma global na sua aplicação, fazendo com que todos os endpoints sejam afetados.
Para que a configuração de Cross-Origin funcione de forma global vamos precisar criar uma classe de configuração com um @Bean
que vai retornar a nossa configuração toda vez que acontece o start da aplicação.
package com.artefatox.example.controller;
import org.springframework.context.annotation.Bean;
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 WebConfiguration {
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("*");
}
};
}
}
JavaLembrando essas configurações devem ser pensadas para o tipo de aplicação que você está desenvolvendo, se precisar de uma configuração mais restritiva é possível setar as configurações para que sejam aceitos somente alguns domínios, ou alguns métodos ou até permitir apenas alguns headers. Ex.
package com.artefatox.example.controller;
import org.springframework.context.annotation.Bean;
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 WebConfiguration {
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/api/v1/**")
.allowedOrigins("example1.com", "examplo2.com")
.allowedHeaders("Authorization", "Content-Type", "Accept")
.allowedMethods("GET", "POST", "PUT");
}
};
}
}
JavaAgora com o Cross-Origin devidamente configurado pode fazer todos os testes necessários e verá que o erro que estava recebendo no front-end não acontece mais.
Se o erro persiste mesmo tendo feito as devidas configurações, vale lembrar que é importante verificar na sua aplicação front-end se o jeito como está sendo chamado o recurso está correto, se a chamada está passando todos os headers necessários.
Bibliotecas como o Axios que é bastante utilizada com aplicações escritas em React por exemplo, tendem a apresentar erro de CORS, mesmo a chamada apresentando outros tipos de erros, então vale uma análise mais detalhada do erro.
Aqui está alguns exemplos de headers que podem ser passados na requisição que ajudam com esses erros:
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Authorization",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS, PUT, PATCH, DELETE"
Text