[항해 99] 5주차 WIL(Weekly, I Learned)

gimseonjin616·2022년 7월 25일
0

프로젝트 후기

목록 보기
8/9
post-custom-banner

주차 : 5주차

기간 : 2022.07.16 ~ 2022.07.22

활동 내용 : Java Web Framework - Spring 심화


Chapter 1. 힘차게...? 시작하자!!!

요즘 주변에 여름방학이라고 놀러다니는 친구들이 많다. 하지만 날 놓아주지 않는 항해 99... 너란 녀석...

나들이는 무슨! 나는 힘차게 항해를 떠날 것이다!!!


Chapter 2. 그럼 이번 주에는 무엇을 할 것인가???

이번 주 키워드는 CORS다.

CORS는 교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)로 "추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제"라고 한다.

이 CORS는 예전 행복주택 관련 서비스를 만들면서 겪은 에러의 하나로 쉽게 얘기하면 "나랑 같은 어플리케이션이 아니면 헤더에 우리가 허락한 키 값을 넣어서 와라!" 란 뜻이다.


Chapter 3. 같은 출처????? 같은 어플리케이션???

이 CORS를 이해하기 위해선 이 출처에 대해서 이해해야한다.

위 그림을 보면 같은 도메인 "domain-a.com" 끼리는 Same-origin requests라고 해서 같은 출처라고 하고, 도메인이 다른 "domain-b.com"은 Croo-origin request라고 한다.

즉 도메인이 같으면 같은 출처라고 할 수 있다.

오 그러면 같은 localhost면 출처가 같으니까 Cross-origin requests가 안뜨겠네요?!?!

정답은 아니다. 왜냐하면 포트 번호도 출처의 하나다. 즉, 같은 도메인의 같은 포트여야만 같은 출처라고 할 수 있다. 여기서 도메인에는 같은 프로토콜도 포함되어 있다.

정리

- 같은 프로토콜 : https
- 같은 도메인 : localhost
- 같은 포트 : 8080

이어야 같은 출처라고 할 수 있다.

Chapter 4. 그러면 React와 Spring 사이에는 CORS...?

구글에 React Spring CORS를 검색하면 위와 같이 정말 많은 연관 검색어가 있는 것이 보인다.

즉 엄청나게 많은 사람이 고통받은 것이다!!!!!

그러면 CORS는 어떻게 해결하면 될까...?

방법은 크게 두가지다. 하나는 Front 부분에서 proxy 설정을 통해 같은 출처인 척 속이는 방법(이 방법은 개발단계서 많이 쓰인다.), 그리고 Backend 부분에서 CORS 설정을 하는 것이다.

그리고 이번 WIL에서는 서버에서 설정하는 것을 정리하겠다.

Spring에서의 CORS 설정은 매우 쉽다! Configration 하나만 설정해주면 된다.

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("*");
    }
}

addCorsMappings는 "URL"마다 특정 Origins를 허용해준다는 코드로 위 코드는 모든 URL에 모든 출처를 다 허용해준다는 코드다.

물론 실제 배포 단계에서는 우리가 허용한 출처만을 설정해줘야 하지만 지금은 이것으로 충분하다!


Chapter 5. preflight

하.지.만! Spring Security에서는 위 코드를 사용하면 적용이 되지 않는다!!!

기본적으로 Browser에서 Server에 요청을 보내기 전에, preflight라는 것을 보내서 "내가 그 서버에 요청을 보낼 건데 허용된 출처인지 확인해주세요~"라는 확인 과정을 거친다.

이때 사용하는 Http Method는 바로 OPTIONS를 사용한다. 그러나 Spring security는 기본적으로 모든 Method를 제한한다!!!!!

즉 Spring Security가 설정되어 있으면 이 preflight 자체가 필터링 된다. 물론 Authentication Provider가 제공한 token을 가지고 있으면 통과가 되지만, 이 token을 받기 위한 로그인 페이지 자체가 막힐 수 있다.

따라서 OPTIONS로 들어오는 요청을 모두(또는 일부)를 허용해줘야 성공적으로 CORS 허용이 가능하다!

Spring Security Config 코드를 아래와 같이 수정하면 OPTIONS를 허용할 수 있습니다.

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        JWTLoginFilter jwtLoginFilter = new JWTLoginFilter(authenticationManager());
        JWTCheckFilter jwtCheckFilter = new JWTCheckFilter(authenticationManager(), userService);

        http
                .csrf().disable()
                .cors().configurationSource(corsConfigurationSource())
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/api/signup","/api/signin", "/api/users/**").permitAll()
                .antMatchers(HttpMethod.OPTIONS,"/api/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic()
                .and()
                .addFilterAt(jwtLoginFilter, UsernamePasswordAuthenticationFilter.class)
                .addFilterAt(jwtCheckFilter, BasicAuthenticationFilter.class)
        ;
    }

Chapter 6. 이번 주차 마무리

원래 WIL는 일요일날 써야한다. 그러나 이번 주 일요일은... 그냥 쉬고 싶었다... 그래서 화요일 아침에 부랴부랴 쓴다...!

하지만 다음주 일요일에는 꼭 제대로 써야지! 라고 다짐한다.

profile
to be data engineer
post-custom-banner

0개의 댓글