미니프로젝트 시작. 오늘은 API 명세서와 와이어프레임을 짜고, github repository를 새로 팠고, 전체적인 서버 코드를 짰다. 오늘의 TIL에는 CORS의 개념에대해 정리해보려 한다.
: Cross Origin Resource Sharing. 쉽게 말해 허락 받은 프론트엔드만 서버의 응답을 받을 수 있다는 개념. 프론트엔드와 백엔드 협업을 할 때, 각각 서버를 따로 띄우는데 CORS 설정을 하지 않으면 서로 상호작용할 수 없다. CORS는 추가 HTTP 헤더를 사용해서 한 출처에서 실행중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다. 웹 애플리케이션은 리소스가 자신의 출처와 다를 때 교차출처 HTTP 요청을 실행한다.즉, 도메인이 다른 서버끼리 리소스를 주고받는 정책이다.
: 출처. = Scheme + Host + Port. 하나라도 다르면 다른 Origin으로 판단.
https://sports.news.naver.com/news?oid=076&aid=0003983417#foo
의 URL에서
Scheme(일반적으로 Protocol) : "https://"
Host : "sports.news.naver.com"
Path : "/news"
QueryString : "?oid=076&aid=0003983417"
Fragment : "#foo"
로 나눌 수 있다. 여기서 Scheme과 Host, 그리고 :8080, :80 과 같은 Port까지 합친 것을 출처(Origin)이라고 한다.
Access-Control-Request-Method: POST // 요청하려는 메서드 정보
Access-Control-Request-Headers: X-PINGOTHER, Content-Type // 요청에 담길 헤더 정보
그러면 서버는 응답으로 어떤걸 허용하는지에 대한 정보를 담아 돌려준다.
Access-Control-Allow-Origin: https://foo.example // 허용된 origin 정보
Access-Control-Allow-Methods: POST, GET, OPTIONS // 허용하는 메서드
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type //사용가능한 헤더 목록
Access-Control-Max-Age: 86400 //현재의 preflight request를 브라우저가 캐싱 가능한 최대 시간
Access-Control-Allow-Credentials: true
를 보내줘야 브라우저에서 응답을 제대로 받을 수 있다. 여기서는 Access-Control-Allow-Origin 헤더 값이 와일드카드면 안되고 구체적인 Origin을 지정해야 한다.public class WebSecurityConfig {
//...생략
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// ... 생략
http.cors(); // 이걸 넣어야 cors가 허용된다.
}
@Bean
public CorsConfigurationSource corsConfigurationSource(){
CorsConfiguration config = new CorsConfiguration();
// 사전에 약속된 출처를 명시
config.addAllowedOrigin("http://localhost:3000");
// config.addAllowedOrigin("프론트 서버 출처?");
// 특정 헤더를 클라이언트 측에서 사용할 수 있게 지정
// 만약 지정하지 않는다면, Authorization 헤더 내의 토큰 값을 사용할 수 없음
config.addExposedHeader(JwtUtil.AUTHORIZATION_HEADER);
// 본 요청에 허용할 HTTP method(예비 요청에 대한 응답 헤더에 추가됨)
config.addAllowedMethod("*");
// 본 요청에 허용할 HTTP header(예비 요청에 대한 응답 헤더에 추가됨)
config.addAllowedHeader("*");
// 기본적으로는 브라우저에서 인증 관련 정보들을 요청 헤더에 담지 않는데,
// 이 설정을 통해서 브라우저에서 인증 관련 정보들을 요청 헤더에 담을 수 있도록 해줍니다.
config.setAllowCredentials(true);
// 위의 allowCredentials 를 true로 하였을 때,
// allowedOrigin의 값이 * (즉, 모두 허용)이 설정될 수 없도록 검증합니다.
config.validateAllowCredentials();
// 어떤 경로에 이 설정을 적용할 지 명시합니다. (여기서는 전체 경로)
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
일단 CustomSecurityConfig에서 필터체인에 http.cors();로 허용하고, 위와같이
CorsConfigurationSource를 만들어서 Cors를 허용하는 방법이 있다.
이 방법 말고 다른 방법으로도 Cors를 허용하는 방법이 있긴하다.