-
[Spring Security] CORS 에 대하여Java/Spring 2019. 11. 11. 03:26반응형
- CORS (Cross-Origin Resource Sharing)
CORS란 웹 어플리케이션의 도메인이 다른 도메인의 리소스에 대해서 접근이 허용되는지 체크하는 매커니즘입니다. 웹 어플리케이션은 리소스를 요청하는 서버의 도메인, 프로토콜 또는 포트가 다를 경우, cross-origin HTTP request 요청을 실행합니다.
보안상의 이유로, 브라우저는 cross-origin HTTP request에 대해서 same-origin policy를 적용하여 동작합니다. 즉, a.com 이라는 도메인의 클라이언트에서 리소스를 요청할 때는 a.com 이라는 도메인의 서버일 경우에 CORS 문제가 발생하지 않고 정상적으로 동작합니다. 만약 두 도메인이 서로 다르다면, CORS에 대해 Header 설정을 해주어야 cross-origin HTTP request 에 대해서 정상적으로 요청과 응답이 이루어집니다.
CORS 요청의 종류
CORS 요청으로는 Simple request 와 Preflight request 가 있습니다.
Simple request
Simple request 는 Preflight 체크를 하지 않으며, 클라이언트와 서버간에 한 번만 요청과 응답을 주고 받습니다. Simple request 는 아래의 조건들을 만족하면 요청하게 됩니다.
1. 요청 메서드
- GET
- HEAD
- POST
2. 커스텀 헤더를 전송을 하지 말아야 한다.
3. 허용되는 헤더는 다음과 같다.
- Accept
- Accept-Language
- Content-Language
- Content-Type
- Last-Event-ID
- DPR
- Save-Data
- Viewport-Width
- Width
4. Content-Type 헤더의 허용되는 Value 값은 다음과 같다.
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
Preflight request
Simple request 의 조건에 만족하지 않으면 Preflight request 방식으로 요청합니다. Preflight request 는 다른 도메인에 HTTP request 를 전송하기 전에 OPTIONS 메서드로 사전 요청을 통해 서버로부터 안전한 요청인지 응답을 받고, 본 요청을 수행합니다.
Spring Security 에서 CORS 문제에 대해서 간단하게 해결하는 방법입니다.
@Configuration @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig extends WebSecurityConfigurerAdapter { private final UserDetailsServiceImpl userDetailsService; private final JwtProvider jwtProvider; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() ... .and() .cors() .and()...; } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.addAllowedOrigin("http://localhost:3000"); configuration.addAllowedHeader("*"); configuration.addAllowedMethod("*"); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
클라이언트는 axios 를 통해서 간단하게 로그인을 위한 userId 와 password 데이터를 POST 방식으로 전송하고 있습니다.
<script> import axios from 'axios' export default { name: "Login", data() { return { form: { userId: '', password: '' } } }, methods: { tryLogin() { axios.post('auth/login', { userId: this.form.userId, password: this.form.password }) .then((res) => { console.log(res.data); }) .catch((e) => { console.error(e); }) } } } </script>
요청의 Content-Type 이 application/json 이므로, Preflight request 가 발생하여 OPTIONS 메서드로 요청을 보냅니다.
Preflight request 요청으로 200 코드를 받고나서 POST로 본 요청을 수행하여 로그인 요청을 수행합니다.
참고 자료
https://dev.to/effingkay/cors-preflighted-requests--options-method-3024
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
https://homoefficio.github.io/2015/07/21/Cross-Origin-Resource-Sharing/#search
https://stackoverflow.com/questions/40418441/spring-security-cors-filter
반응형'Java > Spring' 카테고리의 다른 글
[Spring Boot] logback 설정 (0) 2020.11.10 [Spring Boot] JSP 설정하기 (0) 2019.12.04 Spring Security 정리 (1) 2019.10.05 [Spring] @Transactional 속성 정리 (0) 2019.09.06 JWT 에 대한 간단 정리 (0) 2019.08.04