Fixing CORS Issues in Spring Boot & React Application

🚀 Introduction

In this quick guide, we will explore solutions for CORS issues while developing full-stack web applications using Spring Boot and React JS. I take the URLs below for the Spring Boot backend app and React App but make sure to change the URLs in the solutions.
Spring Boot backend app: http://localhost:8080
React frontend (http://localhost:5173

When developing a React frontend (http://localhost:5173) that communicates with a Spring Boot backend (http://localhost:8080), you might run into CORS (Cross-Origin Resource Sharing) issues.

A common error message you’ll see in the browser console:

Access to XMLHttpRequest at 'http://localhost:8080/api/auth/login' 
from origin 'http://localhost:5173' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

This happens because browsers block cross-origin requests unless the backend explicitly allows them.

🔍 What is CORS?

CORS is a security mechanism that prevents unauthorized websites from making requests to your API. If your backend doesn't whitelist the frontend's origin (http://localhost:5173), browsers will block the request.

To resolve this, you need to configure your Spring Boot backend to allow requests from your React frontend.

✅ Solutions to Fix CORS Issues

1️⃣ Fix Using @CrossOrigin in Controller (Basic Fix)

The simplest way to allow CORS is by adding the @CrossOrigin annotation to your Spring Boot controllers.

Modify your AuthController.java:

@CrossOrigin(origins = "http://localhost:5173")  // Allow requests from frontend
@AllArgsConstructor
@RestController
@RequestMapping("/api/auth")
public class AuthController {
    private AuthService authService;

    @PostMapping("/register")
    public ResponseEntity<String> register(@RequestBody RegisterDto registerDto) {
        String response = authService.register(registerDto);
        return new ResponseEntity<>(response, HttpStatus.CREATED);
    }

    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestBody LoginDto loginDto) {
        String response = authService.login(loginDto);
        return new ResponseEntity<>(response, HttpStatus.OK);
    }
}

🔹 This allows only this specific controller to accept requests from http://localhost:5173.

📌 Limitation: You need to add @CrossOrigin to every controller, which isn't ideal for large applications.

For better maintainability, configure CORS globally by creating a dedicated CORS config class.

Create CorsConfig.java

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 CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("http://localhost:5173") // Allow frontend origin
                        .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")
                        .allowedHeaders("*")
                        .allowCredentials(true);
            }
        };
    }
}

✅ This applies CORS settings to all endpoints, ensuring requests from http://localhost:5173 are always allowed.

📌 Best for: Large applications where multiple controllers need CORS handling.

3️⃣ Enable CORS in Spring Security (For Secured APIs)

If you're using Spring Security, you must explicitly allow CORS.

Modify SpringSecurityConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
public class SecurityConfig {
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(AbstractHttpConfigurer::disable)
            .cors(withDefaults()) // Enable CORS
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(HttpMethod.POST, "/api/**").hasRole("ADMIN")
                .requestMatchers(HttpMethod.PUT, "/api/**").hasRole("ADMIN")
                .requestMatchers(HttpMethod.DELETE, "/api/**").hasRole("ADMIN")
                .requestMatchers(HttpMethod.GET, "/api/**").hasAnyRole("ADMIN", "USER")
                .requestMatchers(HttpMethod.PATCH, "/api/**").hasAnyRole("ADMIN", "USER")
                .requestMatchers(HttpMethod.POST, "/api/auth/**").permitAll()  // Allow auth routes
                .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .anyRequest().authenticated()
            )
            .httpBasic();

        return http.build();
    }
}

✅ This ensures Spring Security does not block CORS requests.

📌 Best for: APIs using authentication & role-based access control.

4️⃣ Configure Spring Boot application.properties

Another simple way to enable CORS is by modifying your application.properties:

# Enable CORS globally
spring.web.cors.allowed-origins=http://localhost:5173
spring.web.cors.allowed-methods=GET,POST,PUT,DELETE,OPTIONS
spring.web.cors.allowed-headers=*
spring.web.cors.allow-credentials=true

✅ This method is easier but less flexible than a dedicated CorsConfig.java file.

🔄 Testing Your Fixes

After applying any of these fixes, follow these steps:

1️⃣ Restart your Spring Boot backend.
2️⃣ Clear browser cache.
3️⃣ Test using Postman to confirm API responses.
4️⃣ Try logging in from the React frontend.

If everything is configured correctly, your requests should now go through without CORS errors! 🎉

🛠 Still Facing Issues? Debugging Tips

🔹 Check the browser console (F12 > Console) to see if CORS headers are present in API responses.
🔹 Inspect network requests (F12 > Network > Fetch/XHR).
🔹 Use Postman to confirm if the backend is responding correctly.
🔹 Check for conflicting security configurations in your backend.

📢 Conclusion

Fixing CORS issues in a Spring Boot & React app is crucial for seamless frontend-backend communication. The best approach depends on your project structure:

✅ Use @CrossOrigin for small apps.
✅ Use Global CORS Config (CorsConfig.java) for large applications.
✅ If using authentication, ensure Spring Security allows CORS.
✅ Always test with Postman and check browser console logs.

By following this guide, your students should be able to solve any CORS issues in their Spring Boot and React projects. 🚀🔥

Happy Coding! 😊👨‍💻👩‍💻

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare