简体   繁体   中英

Spring-Boot RestController fails during CORS

I am trying to write a CORS REST service. By that I mean a REST service that I can call from a website that is hosted on a web server with just a different port than the REST server.

I am using whatwg-fetch (a polyfill for Fetch API client side) and spring-boot for the REST service.

package se.beta.note.rest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import se.selenwall.note.domain.Note;
import se.selenwall.note.domain.repository.NoteRepository;

import java.util.List;

@CrossOrigin(origins = "http://localhost:8001")
@RestController
public class NoteController {
    @Autowired
    private NoteRepository repository;

    @RequestMapping("/note")
    public List<Note> getNotes() {
        List<Note> notes = repository.findAll();
        System.out.println(notes);
        return notes;
    }

    @RequestMapping(value = "/note", method = RequestMethod.POST)
    public void saveNote(@RequestBody @Validated Note note) {
        repository.save(note);
    }
}

The code above work great with GET requests, but the POST fails. Access-Control-Allow-Origin isn't set in the response to the client. But, it is set for the OPTIONS method during preflight. I am not in control over how OPTIONS and POST are sent, I am just using whatwg-fetch and perform a POST, the middleware is then doing the OPTIONS and POST by itself. But the main question is why my RestController isn't responding with Access-Control-Allow-Origin on the POST request?

(I am not using any authorization at all, and the return code is 403 Forbidden on the POST request.)

Uppdate! The 403 Forbidden wasn't related to CORS as I suspected but to CSRF. The CSRF token is missing on the POST request. And this is now another issue I'm facing :D The CSRF token that should be sent in the POST request is sent to the client as a header in the response of the OPTIONS request. And when using whatwg-fetch I just can't reach them as whatwg-fetch handledare preflight and POST automatically. Any ideas annons?

delete @CrossOrigin anotation in NoteController.class

create SimpleCORSFilter add this code

@Component
public class SimpleCORSFilter implements Filter {

    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, GET, PUT, OPTIONS, DELETE, PATCH");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        response.setHeader("Access-Control-Expose-Headers", "Location");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}

You need to instruct Spring on how to deal with CORS requests. Either using a servlet filter, or using Spring's @CrossOrigin annotation, or the CorsRegistry . This guide is pretty handy to get you going https://spring.io/guides/gs/rest-service-cors/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM