If you’ve ever seen the error:
“Access to fetch at ‘http://localhost:8080/api’ from origin ‘http://localhost:3000’ has been blocked by CORS policy”,
then you already know the frustration of CORS.
But don’t worry — in this article, I’ll explain what CORS is and how to configure it in Spring Boot, step by step properly.
🔍 What is CORS?
CORS stands for Cross-Origin Resource Sharing.
It’s a security feature implemented by browsers to prevent JavaScript on one domain (e.g., localhost:3000
) from making requests to another domain (e.g., localhost:8080
) unless the server explicitly allows it.
This is very common in frontend-backend setups — like React or Angular (frontend) calling a Spring Boot API (backend).
🛠️ How to Fix CORS in Spring Boot
There are multiple ways to handle CORS in Spring Boot. You can pick the one that fits your use case best.
✅ 1. Global CORS Configuration (Recommended)
If you want to allow CORS for all controllers, create a configuration class:
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 WebConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true);
}
};
}
}
🔁
allowedOrigins
— define which domains can access your API
📦allowedMethods
— control what HTTP methods are allowed
🔐allowCredentials(true)
— use this if your request includes cookies or auth headers
✅ 2. Controller-Level CORS Configuration
If you only want to allow CORS on specific endpoints:
@CrossOrigin(origins = "http://localhost:3000")
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users")
public List<User> getUsers() {
return List.of(new User(1, "John"));
}
}
You can also customize:
@CrossOrigin(
origins = "http://localhost:3000",
methods = {RequestMethod.GET, RequestMethod.POST},
allowedHeaders = "*"
)
✅ 3. Spring Security CORS Configuration (If Using Spring Security)
If you’re using Spring Security, global CORS settings won’t work unless you enable it in the security config:
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors() // Enable CORS
.and()
.csrf().disable()
.authorizeRequests()
.anyRequest().permitAll();
return http.build();
}
}
Then define a bean for CORS configuration:
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
❗ Common CORS Mistakes
- 🚫 CORS must be handled on the server-side, not in frontend code.
- 🧪 Don’t use
allowedOrigins("*")
withallowCredentials(true)
— browsers will block it. - 💻 Always test CORS using browser tools or Postman (but note: Postman doesn’t enforce CORS rules like browsers do).
🧪 Testing CORS
Use your browser’s DevTools > Network tab to check for CORS errors or inspect the Response Headers.
Look for:
Access-Control-Allow-Origin: http://localhost:3000
📌 Summary
CORS errors are frustrating but easy to fix in Spring Boot.
Choose from:
- Global CORS config (for all routes)
- Controller-level
@CrossOrigin
- Security-based CORS (if using Spring Security)
Set the allowed origins, methods, and headers based on your frontend needs, and you’re good to go!
🔗 You Might Also Like
👉 REST API in Spring Boot Explained Clearly
👉 Asynchronous JavaScript: Promises, Async/Await, and Callbacks
Arsalan Malik is a passionate Software Engineer and the Founder of Makemychance.com. A proud CDAC-qualified developer, Arsalan specializes in full-stack web development, with expertise in technologies like Node.js, PHP, WordPress, React, and modern CSS frameworks.
He actively shares his knowledge and insights with the developer community on platforms like Dev.to and engages with professionals worldwide through LinkedIn.
Arsalan believes in building real-world projects that not only solve problems but also educate and empower users. His mission is to make technology simple, accessible, and impactful for everyone.