SpringBoot 2.7+ CORS ์ด์ ๋ฐ ํด๊ฒฐ๋ฐฉ๋ฒ
๊ฐ๋จํ๊ฒ ๋ง๋ API ์๋ฒ๋ฅผ ํ ์คํธ ํ๊ธฐ ์ํด ๋ก์ปฌ์์ ๋๋ฆฌ๋ ๋์ค ํด๋น ์ด์๋ฅผ ๋ง๋ฌ๋ค.
๊ตฌ์ฑ์ ๋ค์๊ณผ ๊ฐ๋ค.
- localhost:8080/users - SpringBoot API Server ์์ ์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ฆฌํด.
- localhost:8090/index.html - API์๋ฒ๋ก ์์ฒญ์ ๋ณด๋ด๋ ์คํฌ๋ฆฝํธ๊ฐ ์๋ html ํ์ด์ง
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
{{ message }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: '์๋
ํ์ธ์ Vue!'
},
created: function () {
var vm = this;
vm.test();
},
methods: {
test: function () {
axios.post('http://localhost:8080/users', {
params: ''
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
}
})
</script>
</body>
</html>
๊ฐ๋จํ๊ฒ nginx Docker๋ก ํด๋น ํ์ด์ง๋ฅผ 8090ํฌํธ๋ก ๋์ ๋ค.
FROM nginx:alpine
COPY . /usr/share/nginx/html
๊ทธ๋ฆฌ๊ณ ๋๋ง์ CORS ์ด์๋ฅผ ๋ง๋ฌ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ฒ์ํด๋ณธ ๊ฒฐ๊ณผ ์๋์ ๊ฐ์ ๋ฐฉ๋ฒ์ด ์๋ค.
์ ์ผ ๊ฐ๋จํ๊ฒ ๋ด ํ๋ฉด์์๋ง ์๋์ค๊ฒ ํ๊ณ ์ถ๋ค!
Allow CORS: Access-Control-Allow-Origin
Easily add (Access-Control-Allow-Origin: *) rule to the response header.
chrome.google.com
ํด๋น ํ์ฅํ๋ก๊ทธ๋จ์ ๊น๋ฉด ์์์ ํด๋น ์ด์๊ฐ ์๋์ค๋๋ก ์ค์ ํด์ค๋ค. ๋ด ํ๊ฒฝ์์๋ง ์ค๋ฅ๋ฅผ ์๋๊ฒ ํ๊ณ ์ถ๋ค๋ฉด ์ด๋ ๊ฒ ํด๋ ์๊ด ์๋ค.(๋ฌผ๋ก ํฌ๋กฌ ํ์ )
SpringBoot์์ AllowOrigin ํ๋ ๋ฐฉ๋ฒ
์ฒซ๋ฒ์งธ๋ Spring Boot ์์ WebMvcConfigurer๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฉํด์ฃผ๋ ๊ฒ์ด๋ค.
ํด๋น ๋ฐฉ์์ Config ์ธ์๋ @CrossOrigin ์ด๋ผ๋ ์ด๋
ธํ
์ด์
์ผ๋ก ์ปจํธ๋กค๋ฌ ๋ง๋ค ์ค์ ์ด ๊ฐ๋ฅํ๋ค.
์ฐ์ ์์ค๋ ์๋์ ๊ฐ์ด ์ ์ฉํ๋ค.
package rest.api.sample.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST")
.maxAge(3000);
}
}
์๋ฒ์ ์ ์์ค๋ฅผ ์ ์ฉํ๊ณ ๋๋ ค๋ณด๋, ๋ธ๋ผ์ฐ์ ๋ง๋ค ๋ฐ์์ด ๋ฌ๋๋๋ฐ ํฌ๋กฌ์ ์ฌ์ ํ CORS ์ด์ ๋๋ฌธ์ ์๋ต์ ๊ฐ์ ธ์ค๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅ ํ๊ณ , ์ฌํ๋ฆฌ์์๋ ์์ฒญ์ ๋ํ ์๋ต์ ๊ฐ์ ธ์ฌ ์ ์์๋ค.
๊ทธ๋ ๋ค๊ณ ์ฌํ๋ฆฌ์์๋ง ํ ์๋ ์๋ ๋ ธ๋ฆ์ด๋ผ ๋ ์ฐพ์๋ณด๋ ์๋์ ๊ฐ์ ๊ธ์ ์ฐพ๊ฒ ๋์๋ค.
https://howtolivelikehuman.tistory.com/191
Spring Boot CORS header 'Access-Control-Allow-Origin' ์๋ฌ
Spring Boot๋ฅผ ์ฌ์ฉํ๋ฉด์ Rest API ๋ฐฉ์์ ๊ตฌํํ๋ค๋ณด๋ฉด, Postman๊ฐ์ ํ๋ก๊ทธ๋จ์์๋ ์๋ง ์๋๋๋๋ฐ ์ค์ ์คํ์์๋ ์๋ฌ๊ฐ ๋ฐ์ํ ๋๊ฐ ์๋ค. React (Node.js) : http://localhost:3000 Spring boot : http..
howtolivelikehuman.tistory.com
์ดํด๋ณด๋ ๋์ผํ๊ฒ ๋ฐ์ํ๋ ์ํฉ์ด์๊ณ ์ ์ฒ๋ผ ์ค์ ์ ์ ์ฉํด๋ ํ ์ ์์๋ค๊ณ ํ๋ฉฐ, SpringSecurity์ WebSecurityConfigurerAdaptor๋ฅผ ์ฌ์ฉํ๋ผ๊ณ ํ๋ค.
ํ์ฌ ์ ์ฉ ๊ฐ๋ฅํ๊ฐ ์ดํด๋ณด๋ ๋ฒ์ ์ด์๊ฐ ์์๋ค. ๋ฐ๋ก SpringBoot 2.7 ์ด์ ๋ฒ์ ์์๋ ํด๋น ํด๋์ค๋ฅผ ์ง์ํ์ง ์๋ ๋ค๋ ๊ฒ.
https://honeywater97.tistory.com/264
[SpringBoot] WebSecurityConfigurerAdapter ์ง์ ๋ถ๊ฐ
ํ๊ฒฝ - SpringBoot 2.7 - Java17 - Spring Security //spring security implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.security.oauth.boot:spri..
honeywater97.tistory.com
๊ทธ๋์ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํํฐ๋ฅผ ํตํด ํด๋น ์ด์๋ฅผ ํด๊ฒฐํ์๋ค๊ณ ํ์๋ค.
๋ฐ๋ผ์, CORS ํํฐ๋ฅผ ์ ์ฉํ์ฌ ํด๊ฒฐํ ์ฌ๋ก๋ฅผ ์ฐพ์๋ณด์๋ค.
CORS Filter๋ฅผ ์ด์ฉํ ๋ฐฉ๋ฒ
CorsFilter.java
package rest.api.sample.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods",
"ACL, CANCELUPLOAD, CHECKIN, CHECKOUT, COPY, DELETE, GET, HEAD, LOCK, MKCALENDAR, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, REPORT, SEARCH, UNCHECKOUT, UNLOCK, UPDATE, VERSION-CONTROL");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Key, Authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
public void init(FilterConfig filterConfig) {
// not needed
}
public void destroy() {
// not needed
}
}
ํด๋น ์์ค๋ ์๋ ๊ธ์์ ์ฐพ์๋ค.
https://stackoverflow.com/questions/40418441/spring-security-cors-filter
Spring security CORS Filter
We added Spring Security to our existing project. From this moment on we get a 401 No 'Access-Control-Allow-Origin' header is present on the requested resource error from the our server. That's bec...
stackoverflow.com
์ ํํฐ๋ฅผ ์ ์ฉ ํ ํ ์คํธ๋ฅผ ํด๋ณด์๋ค.
๊ฒฐ๊ณผ๋ ์ ๋์ค๋ ๊ฒ์ผ๋ก ํ์ธ ๋์๋ค.
์ WebConfigurer ์ค์ ์ผ๋ก๋ ์๋๊ณ ํํฐ์์ ์ฑ๊ณต์ ํ์๋ ์ดํด๋ณด๋ ๋ฌธ์ ๋ Response์ ํค๋์ ์์๋ค. ์์ ์๋ฌ์์ ๋์จ๋๋ก
"CORS(Cross-Origin Resource Sharing)๋ฅผ ํ๊ธฐ ์ํด header์ ๋ณด๋ด๋ ํค(Access-Control-Allow-Origin)์ด ์๋ค" ๋ ๊ฒ์ด์๋ค.
๋ฐ๋ผ์ ํํฐ ์ชฝ์์ Response์ ์๋ต ํค๋์ ํด๋น ๊ฐ์ ์ธํ
ํด ์ค์ผ๋ก์จ ํฌ๋กฌ์์๋ ํด๋น ์ด์๋ฅผ ์ก์ง ์๋๋ก ์ค์ ํ๋ ๊ฒ์ด ๊ฐ๋ฅ ํ๋ค.
ํด๋น ํํฐ๋ ํ๋์ฏค ์ธํ
ํด๋๊ณ on/off ๋๋ ์ฃผ์ ์ฒ๋ฆฌ๋ฅผ ํตํด ์ธํ
ํ๋ ๊ฒ์ ๊ฐ์ง๊ณ ์๋ ๊ฒ์ด ์ข๊ฒ ๋ค.