没有弹簧安全性的 Spring Boot + React CORS 问题

Posted

技术标签:

【中文标题】没有弹簧安全性的 Spring Boot + React CORS 问题【英文标题】:Spring Boot + React CORS issue without spring security 【发布时间】:2020-08-09 02:34:00 【问题描述】:

我使用 Spring Boot 2.2.2.RELEASE 作为 REST 服务并使用 React 作为前端。

只是实现了一个简单的 GET 方法,但是在通过 REACT 与服务器通信时遇到了 CORS 问题。

https://spring.io/guides/gs/rest-service-cors/ -> 关注了这个链接,但没有运气。

我的 Spring Boot 控制器:

@RestController
public class FeedController 
    @Autowired
    private IFeedService IFeedService;

    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping(path="/v1/getdashboard")
    public ResponseEntity<String> feedDashBoardController()
        String result = null;
        HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
        try 

             List<FeedData> dashBoardFeedInfo = IFeedService.getDashBoardFeedService();

             // Create ObjectMapper
            ObjectMapper mapper = new ObjectMapper();
            JsonNode dataNode = mapper.valueToTree(dashBoardFeedInfo);

            result = FeedResponseData.generateFeedResponse(dataNode);
            httpStatus = HttpStatus.OK;

        catch(TBServiceException e) 
            result = AppExceptions.handleException("Something Went Wrong");
            httpStatus = HttpStatus.BAD_REQUEST;
        

        return new ResponseEntity<String>(result,httpStatus);
    

我的 Spring Boot 应用程序:

@SpringBootApplication
public class TechnicalBlogApplication 

    public static void main(String[] args) 
        SpringApplication.run(TechnicalBlogApplication.class, args);
        System.out.println("Application Main - Update -1");

    

    @Bean
    public WebMvcConfigurer corsConfigurer() 
        return new WebMvcConfigurer() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry.addMapping("/v1/getdashboard").allowedOrigins("http://localhost:3000");
            
        ;
    

我的 Spring 应用程序属性:

spring.profiles.active=dev
server.port=6001
server.servlet.context-path=/technical-blog

我的 React 代码片段:

async componentDidMount() 
const dashboardData= await fetch("http://localhost:6001/technical-blog/v1/getdashboard");

console.log("dash ",dashboardData)

我也试过设置标题,下面是重新修改的控制器。我遇到了多 CORS 定义错误。

@RestController
public class FeedController 
@Autowired
private IFeedService IFeedService;

@CrossOrigin(origins = "http://localhost:3000")
@GetMapping(path="/v1/getdashboard")
public ResponseEntity<String> feedDashBoardController()
    String result = null;
    HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
    try 

         List<FeedData> dashBoardFeedInfo = IFeedService.getDashBoardFeedService();

         // Create ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        JsonNode dataNode = mapper.valueToTree(dashBoardFeedInfo);

        result = FeedResponseData.generateFeedResponse(dataNode);
        httpStatus = HttpStatus.OK;

    catch(TBServiceException e) 
        result = AppExceptions.handleException("Something Went Wrong");
        httpStatus = HttpStatus.BAD_REQUEST;
    

    return new ResponseEntity<String>(result,setHeaders(),httpStatus);



private HttpHeaders setHeaders() 
    List<HttpMethod> allowedMethods = new ArrayList<>();
    allowedMethods.add(HttpMethod.GET);
    allowedMethods.add(HttpMethod.POST);

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    //httpHeaders.setAccessControlAllowOrigin("*");
    httpHeaders.setAccessControlAllowCredentials(true);
    httpHeaders.setAccessControlAllowMethods(allowedMethods);
    httpHeaders.setAccessControlMaxAge(3600);
    return httpHeaders;

【问题讨论】:

【参考方案1】:

我认为您应该将 @CrossOrigin(origins = "http://localhost:3000") 放在它自己的控制器上,因为请求的第一件事是控制器而不是功能

原来是这样的

@RestController
@CrossOrigin(origins = "http://localhost:3000")
public class FeedController 
@Autowired
private IFeedService IFeedService;


@GetMapping(path="/v1/getdashboard")
public ResponseEntity<String> feedDashBoardController()
    String result = null;
    HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
    try 

         List<FeedData> dashBoardFeedInfo = IFeedService.getDashBoardFeedService();

         // Create ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        JsonNode dataNode = mapper.valueToTree(dashBoardFeedInfo);

        result = FeedResponseData.generateFeedResponse(dataNode);
        httpStatus = HttpStatus.OK;

    catch(TBServiceException e) 
        result = AppExceptions.handleException("Something Went Wrong");
        httpStatus = HttpStatus.BAD_REQUEST;
    

    return new ResponseEntity<String>(result,setHeaders(),httpStatus);


【讨论】:

您要我设置标题吗?它不是这样工作的。 不是标题,我说的是请求本身,当涉及到服务器端时,首先要做的是匹配 url,然后它会到达每个控制器并匹配前缀路由并且应该允许它这样做

以上是关于没有弹簧安全性的 Spring Boot + React CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot + Spring Boot 安全启动错误

如何配置弹簧安全性

Spring boot - Apache 反向代理背后的 Spring 安全性

使用Spring Boot Starter安全性中的Custom登录页面成功登录,没有进入下一页

Spring Boot 运行失败

Spring Boot安全主体用户已更改为新登录的用户详细信息