๐CORS๋?
Cross-Origin-Resource-Sharing Polict์ ์ฝ์๋ก ๋ค๋ฅธ ์ถ์ฒ์ ์์์ ๊ณต์ ํ ์ ์๋๋ก ์ค์ ํ๋ ๊ถํ ์ฒด์ ์ด๋ค.
์๋ฅผ ๋ค์ด ๋ด๊ฐ ์คํ๋ง ํ๋ก์ ํธ๋ 9000๋ฒ ํฌํธ์์ ์ด์๋๋ฐ ๋ฆฌ์กํธ๋ 3000๋ฒ ํฌํธ์์ ์ด์๋ค๋ฉด cors ์ค์ ์ ์ ๋๋ก ํด์ฃผ์ง ์๋ ๊ฒฝ์ฐ ์ํ๋ ๋๋ก ๋ฆฌ์์ค๋ฅผ ๊ณต์ ํ์ง ๋ชปํ๋ค.
์ด๋ฐ CORS ๋ณด์์ ์ฑ ์ด ๋ฐ์ํ๋ ์ด์ ๋ SOP(Same Origin Policy) ๋๋ฌธ์ธ๋ฐ ๋์ผํ ์ถ์ฒ์ Origin๋ง ๋ฆฌ์์ค๋ฅผ ๊ณต์ ํ ์ ์๊ฒ ํ๋ ์ญํ ์ ํ๋ค. ๋ง์ผ ๋์ผํ ์ถ์ฒ๊ฐ ์๋๋ผ๋ฉด ์ฌ๋ฌ options๋ฅผ ์ด์ฉํด preflight๋ฅผ ์ด์ฉํด์ ์ฌ๋ฌ ๊ฒ์ฆ์ ๊ฑฐ์น๋ค.
[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๋ฅผ ํตํด ํด๋น ํด๋์ค๋ฅผ ์คํ๋ง ์ปจํ ์ด๋์ ๋น์ผ๋ก ๋ฑ๋กํ ์ ์๋ค.
[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 |
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์์กด์ฑ ์ฃผ์ ์ ๋ถํธ ๋ณด๋จ ์คํ๋ง ํ๋ก์ ํธ๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ ์ ํฉํ ๊ฒ ๊ฐ์๋ค.
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๋ ํด์ผํ๋ค
[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
(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