Todo dev tem ou já teve total pavor dessa palavra cors, aquele que nasceu para nos ajudar mas acaba dificultando o nosso trabalho, por pura falta de entendimento de como é o seu pleno funcionamento, que convenhamos, é bem simples, né?
Mas a nossa missão hoje não é explicar como funcionar o CORS, mas sim resolvermos um problema bem comum que pode acontece quando estamos utilizando o Spring Security e uma aplicação em Angular (aliás, qualquer outra que use HTTP)
Essa simples mistura de Angular rodando por padrão localmente em seu ambiente de desenvolvimento na porta 4200, e o seu backend com Spring Boot, provavelmente em paralelo rodando na porta 8080 já podem acarretar um problema de cors.
Configurando o Spring:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:4200").allowedMethods("PUT", "DELETE", "GET", "POST").allowedHeaders("*"); } }
Devemos criar uma classe de configuração, no exemplo eu criei uma chamada WebConfig, ela deverá implementar a interface WebMvcConfigurer e em seguida devemos gerar a implementação do método addCorsMapping que recebe como parâmetro o CorsRegistry, objeto passado por referência que é responsável pelo registro dos headers que possibilitam a comunicação entre as duas partes.
- AddMapping: Adicionamos o pattern das url’s da API, no caso tudo “/**“
- allowedOrigins: colocamos a origem permitida, no nosso caso http://localhost:4200 (origem do Angular em dev)
- allowedMethod: métodos permitidos nas requisições
Configuração com Spring Security:
Quando estamos utilizando Spring Security devemos ter uma abordagem um pouco diferente, devemos aplicar o cors na configuração dos nosso endpoints seguros, como no exemplo abaixo:
@Throws(Exception::class) override fun configure(http: HttpSecurity) { http.authorizeRequests() .anyRequest() .authenticated().and().csrf() .disable().cors().and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and().addFilterBefore(AuthenticationFilter(tokenService), UsernamePasswordAuthenticationFilter::class.java) }
Observamos que apos aplicarmos o csrf devemos desabilitar o cors, essa abordagem é bem simples, porém pode causar muita dor de cabeça caso você esqueça de configurar.
Considerações finais:
Desenvolver uma integração nem sempre pode ser uma tarefa fácil, mas com essas dicas acredito que irei poupar um bom tempo perdido nas suas integrações de API’s.
Até mais.