Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS error when connecting local React frontend to local Spring Boot middleware application

I am working on a frontend application in React that connects to a middleware service written in Spring boot. I am attempting to call an endpoint from the front end as follows:

return axios.post('http://localhost:8085/workshop/client/createClient', {username})
.then((response) => {
  console.log('Success')
})
.catch((error) => console.log(error));

Whenever I make the request in my browser I get the following errors:

OPTIONS http://localhost:8085/workshop/client/createClient 401 ()

Failed to load http://localhost:8085/workshop/client/createClient: Response for preflight has invalid HTTP status code 401.

As far as I understand, this is because the preflight request is being blocked by my middleware application. Having read a bit online about enabling this, I have added a CorsFilter to my spring boot application:

@Slf4j
public class CORSFilter implements Filter {
  private static final String ONE_HOUR = "3600";

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }

  @Override
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", ONE_HOUR);
    response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type, Accept, x-device-user-agent, Content-Type");

    if (req instanceof HttpServletRequest) {
       HttpServletRequest httpServletRequest = (HttpServletRequest) req;
       if (httpServletRequest.getHeader(HttpHeaders.ORIGIN) != null
          && httpServletRequest.getMethod().equals(HttpMethod.OPTIONS.name())
          && httpServletRequest.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null) {
          log.debug("Received an OPTIONS pre-flight request.");
          return;
       }
    }
    chain.doFilter(req, res);
  }

  @Override
  public void destroy() {
  }
}

And

@Configuration
public class MvcConfiguration {

 @Bean
 public FilterRegistrationBean corsFilter() {
   FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
   filterRegistrationBean.setFilter(new CORSFilter());
   filterRegistrationBean.addUrlPatterns("/*");
   filterRegistrationBean.setOrder(0);
   return filterRegistrationBean;
 }
}

Here is an example of the endpoint:

 @PostMapping("/createClient")
 public ResponseEntity<?> createClient(@RequestBody CreateClientDto clientDto) {
    try {
     ...
     return new ResponseEntity<>(responseBody, OK);
    } catch (Exception e ...) {}
  }

Any help would be greatly appreciated :)

Update: I had the url slightly wrong for the request (hence the 404). I have updated the error message. I still seem to be having CORS issues.

These are the response headers that I can see in the dev tools:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:access-control-allow-credentials, access-control-allow-methods, access-control-allow-origin, allow, content-type
Access-Control-Allow-Methods:POST
Access-Control-Allow-Origin:http://localhost:3000
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date:Thu, 01 Mar 2018 14:06:38 GMT
Expires:0
Pragma:no-cache
Strict-Transport-Security:max-age=31536000 ; includeSubDomains
Vary:Origin
WWW-Authenticate:Basic realm="Spring"
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

And the request headers:

OPTIONS /workshop/client/createClient HTTP/1.1
Host: localhost:8085
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
Access-Control-Request-Headers: access-control-allow-credentials,access-control-allow-methods,access-control-allow-origin,allow,content-type
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,da;q=0.7
like image 399
liamw9 Avatar asked Mar 01 '18 12:03

liamw9


People also ask

How do you fix CORS issue in spring boot and react?

So you have to navigate to the controller in Spring boot java and allow the URL of Reactjs to be given the permission for accessibility in the server (Spring boot). This will help you get rid of the CORS issue.

How do I fix the CORS issue in localhost react?

One of the work around is to add a “proxy” property to your package. json file and assign your service base url to it. Thus, any request made on your react app will be proxied to http://localhost:8080/api/* or https:my-service.com/api/*, as against your React client origin via http://localhost:3000/api/*.

How do you turn on CORS spring boot react?

Configure CORS for Spring Bootjava and add a @CrossOrigin annotation to enable cross-origin resource sharing (CORS) from the client ( http://localhost:3000 ). After making these changes, restart the server, refresh your browser, and you should be able to see a list of beers from your Spring Boot API.


2 Answers

I also had this issue, but allow me to give a straight forward answer in a simpler communication manner.

First and foremost, you have to tell your server (Spring boot java), about the client (Reactjs ) URL.

For example, most of the times spring boot uses http://localhost:8080 and Reactjs uses http://localhost:3000.

So you have to navigate to the controller in Spring boot java and allow the URL of Reactjs to be given the permission for accessibility in the server (Spring boot). This will help you get rid of the CORS issue.

How do we do this in Spring boot? simply we add the @CrossOrigin annotation specifying the Reactjs URL link as below:

For example :

    @GetMapping("/orphans")
    @CrossOrigin(origins = "http://localhost:3000")
    Iterable<Student> read() {
        return studentService.findAll();
    }

The method above is to list all the orphans, so I gave Reactjs URL link permission then I got rid of the CORS issue.

Happy coding.

like image 192
Lutaaya Huzaifah Idris Avatar answered Oct 15 '22 18:10

Lutaaya Huzaifah Idris


Controller.java

Refer to the below sample code to resolve this issue.

@CrossOrigin(origins = "http://localhost:3000")
@RequestMapping(value="/sample", method = RequestMethod.GET, produces = "application/json")

public Student getStudent(){
}
like image 30
K Murali Krishna Avatar answered Oct 15 '22 16:10

K Murali Krishna