Springboot/Errors!๐Ÿ’ข

[Springboot,React] CORS ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•

Alchemists 2022. 8. 12. 10:28
728x90

๐Ÿ“ŒCORS๋ž€?

 

Cross-Origin-Resource-Sharing Polict์˜ ์•ฝ์ž๋กœ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์ž์›์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•˜๋Š” ๊ถŒํ•œ ์ฒด์ œ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‚ด๊ฐ€ ์Šคํ”„๋ง ํ”„๋กœ์ ํŠธ๋Š” 9000๋ฒˆ ํฌํŠธ์—์„œ ์—ด์—ˆ๋Š”๋ฐ ๋ฆฌ์•กํŠธ๋Š” 3000๋ฒˆ ํฌํŠธ์—์„œ ์—ด์—ˆ๋‹ค๋ฉด cors ์„ค์ •์„ ์ œ๋Œ€๋กœ ํ•ด์ฃผ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์›ํ•˜๋Š” ๋Œ€๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•˜์ง€ ๋ชปํ•œ๋‹ค. 

 

์ด๋Ÿฐ CORS ๋ณด์•ˆ์ •์ฑ…์ด ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ๋Š” SOP(Same Origin Policy) ๋•Œ๋ฌธ์ธ๋ฐ ๋™์ผํ•œ ์ถœ์ฒ˜์˜ Origin๋งŒ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ๋งŒ์ผ ๋™์ผํ•œ ์ถœ์ฒ˜๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์—ฌ๋Ÿฌ options๋ฅผ ์ด์šฉํ•ด preflight๋ฅผ ์ด์šฉํ•ด์„œ ์—ฌ๋Ÿฌ ๊ฒ€์ฆ์„ ๊ฑฐ์นœ๋‹ค. 

 

https://wonit.tistory.com/571

 

[HTTP] OPTIONS ํ—ค๋”์™€ Preflight ๊ทธ๋ฆฌ๊ณ  CORS

OPTIONS ๋Š” RFC 7231 ์— ๋ช…์‹œ๋œ HTTP์˜ ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ ์ค‘ ํ•˜๋‚˜์ด๋‹ค. OPTIONS ๋Š” ์‹ค์ œ๋กœ ์šฐ๋ฆฌ๊ฐ€ ํ”„๋ ˆ์ž„์›Œํฌ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ง์ ‘ ์‚ฌ์šฉํ•  ์ผ์€ ๋“œ๋ฌผ์ง€๋งŒ ํ˜„๋Œ€์˜ Front Back ์„ ๋‚˜๋ˆ„๋Š” ๊ฐœ๋ฐœ ํ๋ฆ„์—์„œ

wonit.tistory.com

 

 

 

๐Ÿ“Œ ์Šคํ”„๋ง๋ถ€ํŠธ์—์„œ CORS๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•

 

CORS ์„ค๋ช…์€ ์—ฌ๊ธฐ๊นŒ์ง€ ํ•˜๊ณ  ์Šคํ”„๋ง๋ถ€ํŠธ์—์„œ CORS๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ 3๊ฐ€์ง€์ด๋‹ค. ๋‚˜๋Š” ์ฒซ๋ฒˆ์งธ ๋ฐฉ๋ฒ•๋งŒ ์„ฑ๊ณต์ด๋๋‹ค.

 

1. CORSFilter ์ƒ์„ฑํ•˜๊ธฐ 

 

filter๋ผ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ   CorsFilter ํด๋ž˜์Šค๋ฅผ ํ•˜์œ„์— ํ•˜๋‚˜ ์ƒ์„ฑํ•œ๋‹ค. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 
 
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
 
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
 
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
 
        response.setHeader("Access-Control-Allow-Origin""http://localhost:3000");
        response.setHeader("Access-Control-Allow-Credentials""true");
        response.setHeader("Access-Control-Allow-Methods","*");
        response.setHeader("Access-Control-Max-Age""3600");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept, Authorization");
 
        if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        }else {
            chain.doFilter(req, res);
        }
 
    }
 
    @Override
    public void destroy() {
 
    }
}
 
cs

 

@Component๋ฅผ ํ†ตํ•ด  ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—  ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค. 

https://wonit.tistory.com/572

 

[Spring Boot] CORS ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ• (Filter, @CrossOrigin, WebMvcConfigurer)

Server Side Template ๋ฐฉ์‹์ด ์•„๋‹Œ Front์™€ Back ์œผ๋กœ ๋‚˜๋ˆ ์„œ ์ธํ”„๋ผ๋ฅผ ๊ตฌ์„ฑํ•ด๋ณธ ๊ฒฝํ—˜์ด ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” Cors๊ฐ€ ๋งค์šฐ ์นœ์ˆ™ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ˜„์žฌ ๊ฐœ๋ฐœ ํ๋ฆ„์—์„œ ์›น ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋‹ค๊ฐ€ Cors ๋ฅผ ๋งŒ๋‚  ํ™•๋ฅ ์€

wonit.tistory.com


2. WebMvcConfigurer ์„ค์ •

 

์ด ๋ฐฉ๋ฒ•์€ globalํ•˜๊ฒŒ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๋‚˜๋Š” ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ–ˆ์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์„ฑ๊ณตํ•œ ์‚ฌ๋žŒ๋“ค๋„ ๋งŽ์€ ๊ฒƒ ๊ฐ™๋‹ค. ์ด ๋ฐฉ๋ฒ•๋„ ๋‘๊ฐ€์ง€๋กœ ๋‚˜๋‰˜๋Š”๋ฐ ๋‘˜ ์ค‘์— ๋˜๋Š”๊ฑธ๋กœ ๊ณจ๋ผ์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋  ๋“ฏํ•˜๋‹ค.

 

2-1. WebConfig ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์„ค์ •

 

config ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ  ํ•˜์œ„์— WebConfig ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

 

1
2
3
4
5
6
7
8
9
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET""POST")
                .maxAge(3000);
}
cs

https://lovon.tistory.com/156

 

SpringBoot CORS (WebMvcConfigurer ์‚ฌ์šฉ) ์ ์šฉ ๋ฐฉ๋ฒ•

/* preflight Simple request๊ฐ€ ์•„๋‹Œ ์š”์ฒญ ๋ฉ”์‹œ์ง€๋ณด๋‹ค ๋จผ์ € ๋ณด๋‚ด๋Š” ๋ฉ”์‹œ์ง€๋กœ, ๋ธŒ๋ผ์šฐ์ €๋Š” ์‘๋‹ต๊ฐ’์œผ๋กœ ์‹ค์ œ ๋ฐ์ดํ„ฐ ์ „์†ก ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จ. CORS๋Š” ์‘๋‹ต์ด Access-Control-Allow-Credentials: true ์„ ๊ฐ€์งˆ ๊ฒฝ์šฐ, Access..

lovon.tistory.com

https://dev-pengun.tistory.com/entry/Spring-Boot-CORS-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0

 

[Spring Boot] CORS ์„ค์ •ํ•˜๊ธฐ

CORS๋ž€? (Cross-Origin Resource Sharing,CORS) ๋ž€ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์ž์›์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•˜๋Š” ๊ถŒํ•œ ์ฒด์ œ๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ CORS๋ฅผ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š๊ฑฐ๋‚˜ ์ œ๋Œ€๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ์›ํ•˜๋Š”๋Œ€๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ

dev.exd0tpy.xyz

 

 

2-2. Spring ํ”„๋กœ์ ํŠธ์˜ mainํ•จ์ˆ˜์— Bean์œผ๋กœ Configurer๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@SpringBootApplication
public class RestServiceCorsApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(RestServiceCorsApplication.class, args);
    }
 
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("http://front-server.com");
            }
        };
    }
 
}
cs

 

 


3.CrossOrgin ์–ด๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉ

 

์ปจํŠธ๋กค๋Ÿฌ์—์„œ ํŠน์ • ๋ฉ”์„œ๋“œ ํ˜น์€ ์ปจํŠธ๋กค๋Ÿฌ ์ƒ๋‹จ๋ถ€์— @CrossOrigin์„ ์ถ”๊ฐ€ํ•œ๋‹ค. 

 

 

1
2
3
4
5
6
7
8
9
10
11
@RestController
@RequestMapping("/somePath")
public class SomeController {
 
    @CrossOrigin(origins="*")
    @RequestMapping(value = "/{something}",method = RequestMethod.DELETE)
    public ResponseEntity<String> delete(@PathVariable Long reservationNo) throws Exception{
    }
 
}
 
cs

 

๋‚ด๊ฐ€ ์ฐพ์€ ๋ฐฉ๋ฒ•์€ 3๊ฐ€์ง€์ธ๋ฐ build.gradle์— ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๊ทผ๋ฐ ์ด๊ฑด pom.xml์„ ์ˆ˜์ •ํ•ด์•ผํ•˜๋Š”๋ฐ 

์ด ํŒŒ์ผ์€ Maven์˜ ๋นŒ๋“œ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค. ๋‚˜ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ํ”„๋กœ์ ํŠธ์— pom.xml์ด ์—†์—ˆ๋‹ค. ์Šคํ”„๋ง๋ถ€ํŠธ๋Š” ๋นŒ๋“œ ๋„๊ตฌ๋กœ gradle์„ ์“ฐ๋‹ˆ๊นŒ ์—†๋Š”๊ฒƒ์œผ๋กœ ์ถ”์ธกํ•˜๊ณ  ์žˆ๋‹ค(์•„๋‹ˆ๋ผ๋ฉด ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”! ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!)

 

๊ทธ๋ž˜์„œ build.gradle์˜์กด์„ฑ ์ฃผ์ž…์€ ๋ถ€ํŠธ ๋ณด๋‹จ ์Šคํ”„๋ง ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ ์ ํ•ฉํ•  ๊ฒƒ ๊ฐ™์•˜๋‹ค. 

 

 

https://abbo.tistory.com/147

 

Spring ์—์„œ์˜ CORS ํ•ด๊ฒฐ ์ผ์ง€

ํด๋ผ์ด์–ธํŠธ์—์„œ CORS ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ์ด์Šˆ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ์ด ๋ถ€๋ถ„์ด ์„œ๋ฒ„์—๋„ ์ ์šฉ์ด ๋˜์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์–ด ์ถ”๊ฐ€๋กœ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ๋„ CORS๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ๋Š”

abbo.tistory.com

 

 

๐Ÿ“Œ ๋ฆฌ์•กํŠธ CORS ์„ค์ •

 

ํ”„๋ก ํŠธ์—์„œ๋„ CORS ์„ค์ •์„ ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ๋ฆฌ์•กํŠธ ๋‚ด๋ถ€ ์„ค์ •์€ http-proxy-middleware์™€ axios CORS์„ค์ •์„ ํ•ด์ฃผ์—ˆ๋‹ค.

 

1. http-proxy-middleware

 

http-proxy-middleware ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ˆ˜๋™์„ค์ •์„ ํ•œ๋‹ค.

 

npm install http-proxy-middleware

 

ํŠนํžˆ CRA ํ™˜๊ฒฝ์—์„œ ์ž‘์—…์„ ํ• ๋•Œ๋Š” src ํด๋”์—  setupProxy.js ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์ค˜์•ผ ์ œ๋Œ€๋กœ ์•ฑ์ด ํ”„๋ก์‹œ ํŒŒ์‹ฑ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. proxy๊ด€๋ จ ํŒŒ์ผ์€ ๋ฐ˜๋“œ์‹œ ./src์— ์œ„์น˜ํ•ด์•ผํ•œ๋‹ค. 

 

1
2
3
4
5
6
7
8
9
10
const { createProxyMiddleware } = require("http-proxy-middleware");
 
module.exports = function (app) {
  app.use(
    createProxyMiddleware("/api/v1", {
      target: "http://localhost:9000",
      changeOrigin: true,
    })
  );
};
cs

์œ„์™€ ๊ฐ™์ด setupProxy.js ํŒŒ์ผ์„ ์ž‘์„ฑํ•ด์ค€๋‹ค. 

 

 

[axios ์ „์—ญ ์„ค์ •]
axios.defaults.withCredentials = true;

 

๋ฆฌ์•กํŠธ ์ฝ”๋“œ ๋‚ด์— axios ์ „์—ญ ์„ค์ •์„ ํ•ด์ฃผ์—ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  axios ์“ฐ๋ ค๋ฉด ์ƒ๋‹จ์— import๋„ ํ•ด์•ผํ•œ๋‹ค

 

https://inpa.tistory.com/entry/AXIOS-%F0%9F%93%9A-CORS-%EC%BF%A0%ED%82%A4-%EC%A0%84%EC%86%A1withCredentials-%EC%98%B5%EC%85%98

 

[AXIOS] ๐Ÿ“š CORS ์ฟ ํ‚ค ์ „์†กํ•˜๊ธฐ (withCredentials ์˜ต์…˜)

๐Ÿคฌ ๋ฌธ์ œ์  : ์™œ ์•ˆ๋˜๋Š”๊ฑฐ์•ผ? ๋‹ค์Œ ์ƒํ™ฉ์„ ๊ฐ€์ •ํ•ด๋ณด์ž ํ”„๋ก ํŠธ(react) : 3000 / ์„œ๋ฒ„(express) : 3060 ํฌํŠธ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ • ํ”„๋ก ํŠธ์—์„œ axios.post("/post", data)๋กœ ์š”์ฒญ์„ ๋ณด๋ƒ„ > CORS ์„œ๋ฒ„ "/post"์—์„œ req.use..

inpa.tistory.com

 

 

https://hoons-up.tistory.com/26

 

[Develop/React] proxy ์ˆ˜๋™ ์„ค์ •(setupProxy)

proxy ์ˆ˜๋™ ์„ค์ •(setupProxy) ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ถœ์ฒ˜๊ฐ€ ๋‹ค๋ฅธ ์ฆ‰ host๋‚˜ port๊ฐ€ ๋‹ค๋ฅธ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋กœ API ์š”์ฒญ ์‹œ ํ˜ธ์ถœํ•  ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” CORS ๊ด€๋ จ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ Proxy๋ฅผ ์„ค์ •ํ•˜์—ฌ ์ค€๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค

hoons-up.tistory.com

https://velog.io/@yunsungyang-omc/React-React-App%EC%97%90%EC%84%9C-CORS-%EC%9D%B4%EC%8A%88-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0

 

(React) React App์—์„œ CORS ์ด์Šˆ ํ•ด๊ฒฐํ•˜๊ธฐ

CORS๊ฐ€ ๋ฌด์—‡์ธ์ง€, CORS ์ด์Šˆ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ทน๋ณตํ• ์ง€ ์•Œ์•„๋ณด์ž

velog.io

https://artistjay.tistory.com/26

 

[React] axios cors ์—๋Ÿฌ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

React + node express + mysql์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์‹œํŒ ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ์ค‘, CORS ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋”ฐ๋กœ ๋‚ด์šฉ ์ •๋ฆฌ๋ฅผ ํ•œ๋‹ค. CORS๋ž€? Cross Origin Resource Sharing์˜ ์•ฝ์ž๋กœ, ํ˜„์žฌ ์›นํŽ˜์ด์ง€ ๋„๋ฉ”์ธ์—์„œ ๋‹ค๋ฅธ ์›นํŽ˜์ด์ง€ ๋„..

artistjay.tistory.com

https://spring.io/guides/gs/rest-service-cors/

 

Enabling Cross Origin Requests for a RESTful Web Service

this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and techniques as recommended by the Spring team

spring.io

 

728x90