Reputation: 23
I have a Spring boot API rest as a server, and I have an angular JS front-end application. From the front end I'm getting this error:
Access to XMLHttpRequest at 'http://localhost:8080/?latitude=38.902693&longitude=-77.011932' from origin 'http://localhost:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Here are my spring application and its configurations:
WebConfiguration.java:
package com.example.assignment.config;
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;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedOrigins("*")
.allowedHeaders("Content_Type", "Authorization");
}
}
ApplicationConfiguration.java:
package com.example.assignment.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationConfiguration {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
The controller:
package com.example.assignment.chargingStations.controllers;
import com.example.assignment.chargingStations.models.response.ChargingStation;
import com.example.assignment.chargingStations.services.OpenChargeMapService;
import com.example.assignment.chargingStations.services.SecurityService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import java.util.List;
@RestController
public class ChargingStationsController {
private final OpenChargeMapService openChargeMapService;
private final SecurityService securityService;
public ChargingStationsController(OpenChargeMapService openChargeMapService, SecurityService securityService) {
this.openChargeMapService = openChargeMapService;
this.securityService = securityService;
}
@RequestMapping(path = "/nearest-charging-stations", method = RequestMethod.GET)
public ResponseEntity<List<ChargingStation>> getNearestChargingStations(@RequestHeader(value = "Authorization", required = false) String token,
@RequestParam Double latitude,
@RequestParam Double longitude) {
checkToken(token);
securityService.validateToken(token);
List<ChargingStation> nearestChargingStationRequests = openChargeMapService.getNearestChargingStations(latitude, longitude);
return new ResponseEntity<>(nearestChargingStationRequests, HttpStatus.OK);
}
private void checkToken(String token) {
if (token == null || token.equals("")) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Authorization header is missing.");
}
}
}
And the build.gradle:
plugins {
id 'org.springframework.boot' version '2.5.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.projectlombok:lombok:1.18.18'
implementation 'junit:junit:4.13.1'
implementation 'com.auth0:java-jwt:3.16.0'
annotationProcessor 'org.projectlombok:lombok:1.18.18'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
I don't know what I'm doing wrong. All the source-origins are allowed and the methods.
Upvotes: 0
Views: 14375
Reputation: 30088
I'm guessing that the preflight OPTIONS request made by the browser is not being handled by your application - your application is probably returning an HTTP 405 response (Method Not Allowed).
As your error message implies, if the browser's preflight OPTIONS request doesn't get an HTTP 200 response, then the GET request will never be sent.
See my explanation of how CORS works and why you need to support an OPTIONS request at Response for preflight does not have HTTP ok status in angular
Probably the easiest way to solve this is to add
spring.mvc.dispatch-options-request=true
to your application.properties file. This will configure Spring Boot to handle the OPTIONS requests for you, so that you don't need to handle them in your controllers.
For more information on this, see How to handle HTTP OPTIONS requests in Spring Boot?
Upvotes: 6