ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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

    댓글

Designed by Tistory.