🚀 이전 글에서 CORS에 대해 알아봤다.
이제 STOMP를 구현하다가 CORS를 만나게 된 과정에 대해 적고자 한다.
STOMP를 구현하면서 View를 통해 Socket 송수신을 확인했다.
View(ChatRoomList) -> 채팅방 이름 입력 -> 채팅방(Socket) 생성 -> View(ChatRoom) -> 데이터 입력(채팅 메시지) -> 보내기(전송)의 과정을 구현하고자 했다.
하지만 ChatRoomList를 조회하는 페이지에서 처음 CORS를 만나게 되었다.
개발 창(cntrl+shift+i)에서 Header를 확인해보니 'Origin : null'로 되어 있었다.
만약 정상적으로 출처를 받아왔다면 'Origin: http://{도메인}:{포트번호}' 이여야 했다.
Origin이 null이라 Origin이 일치하지 않아 CORS가 발생한 것으로 보였다.
이를 해결하기 위해 구글링을 해보니 WebMvcConfigurer를 통해 Spring 서버를 전역으로 설정하는 방법이 있었다.
config라는 패키지(폴더)를 만든 후 해당 코드를 작성해 이를 적용했다.
// Spring 서버 전역적으로 CORS 설정
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*") // “*“같은 와일드카드를 사용
.allowedMethods("GET", "POST") // 허용할 HTTP method
.allowCredentials(true); // 쿠키 인증 요청 허용
}
}
그런데도 다음과 같은 오류가 발생했다.
When allowCredentials is true, allowedOrigins cannot contain the special value "*"
찾아보니, Spring에서 WebMvcConfigurer에서 CORS 처리를 해주면서 .addAllOrigin("*")를 통해 모든 경로를 열었다.
하지만 allowCredentials(true)와 같이 사용할 수 없다는 것을 알게 되었고, allowCredentials(true)를 삭제하여 문제를 해결했다.
CORS 처리해줌으로써 View(ChatRoomList) -> 채팅방 이름 입력 -> 채팅방(Socket) 생성 -> View(ChatRoom) -> 데이터 입력(채팅 메시지) -> 보내기(전송)의 과정에서 채팅방을 생성하는 것까지는 성공했다.
하지만 채팅방에 입장했을 때 다음과 같은 오류가 발생했다.
java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.
allowCredentials를 true로 사용 중일 때 allowedOrigins을 "*"으로 지정할 수 없다는 로그였고, allowedOrigins 대신 allowed OriginPatterns를 사용하라고 했다.
그래서 코드를 다음과 같이 수정했다. (+다른 코드 수정)
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("Authorization", "Content-Type")
.exposedHeaders("Custom-Header")
.maxAge(3600);
}
}
하지만 동일한 문제가 계속해서 발생했다.
다음 블로그 글을 참고해보니, 클라이언트에서 socketJs로 접근을 시도할 때 allowedOrigins를 사용하고 있다는 것을 알게 되었다.
그래서 setAllowedOrigins를 setAllowedOriginPatterns로 변경하여 문제를 해결했다.
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-stomp").setAllowedOriginPatterns("*").withSockJS();
}