본문 바로가기
Dev/프로젝트 관련 정리

Invalid Host Header 문제 : react 배포 시의 문제

by IMSfromSeoul 2022. 3. 15.

📦 도입

해당 문제는 제가 PostMission이라는 프로젝트를 진행 중일때 만났던 에러입니다.

저희 프로젝트는 프론트는 react:3000번 포트 , 서버는 spring:8080번 포트를 사용해서 구축하였습니다. 

문제는 둘은 같은 domain이지만, 다른 origin이라서 react에서 spring으로 요청을 보낼 시, SOP 정책에 위반돼서 에러가 난다는 것이었습니다.

 

cf) 🔖 여기서 domain과 origin이 헷갈릴 수 있습니다.

  • domain
    • naver.com
  • origin
    • https://naver.com:8080

origin은 프로토콜과 포트번호까지 일치해야 같은 origin이라고 할 수 있습니다.

즉, domain이 좀 더 넓은 범위라고 생각하시면 됩니다.

 

그러나 이 문제는 널리 알려진 문제라서 다음과 같이 쉽게 해결될 것이라 생각했습니다.

  • react 쪽에서는 pacakge.json에 spring origin을 명시해준다.
{ ..., 
"proxy": "http://localhost:8080" 
}
  • spring 쪽에서는 corsConfig 파일을 정의해주어서 CORS를 사용할 수 있게 해준다.

 

🔖 CorsConfig.java

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // server 가 client 에서 json 처리를 javascript 로 할 수 있게 허락
        config.addAllowedOrigin("*"); // 모든 ip 에 응답 허용
        config.addAllowedHeader("*"); // 모든 header 에 응답 허용
        config.addAllowedMethod("*"); // 모든 method 에 응답 허용
        config.setAllowedOrigins(List.of("http://localhost:3000","http://i6a302.p.ssafy.io"));
        config.addExposedHeader("Authorization");
        source.registerCorsConfiguration("/**",config);
        return new CorsFilter(source);
    }
}

 

🔖 SecurityConfig.java

...
private final CorsFilter corsFilter;
	@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .addFilter(corsFilter)
                ...
   }

 

그런데 문제는 위와 같이 CORS 관련 설정을 잘 해주었다고 생각을 했는데, 막상 react app을 실행해보니

아래와 같이 invalid host header라는 텍스트만 화면에 뜨고 web app이 실행되지 않았습니다.

📦 Invalid Host header 에러가 발생하는 이유

This error is most commonly caused by a misconfiguration of the application server that causes it to reject non-local connections.

...

Essentially, only traffic directed to your machine from itself is allowed to pass through, meaning that traffic passing through the tunnel will not work the same as traffic coming from your machine directly. Even though it works on your machine, the way the server is set up makes it so that even other local machines cannot connect to it.

솔직하게 아직도 Invalid Host header 에러가 왜 발생하는 지 정확한 원인은 모르겠습니다.

다만 여러 검색을 통해 알아낸 바로는 외부 서버에서의 환경은 터널을 통해 traffic이 들어가기 때문에 local에서의 환경과 다르므로 서버 환경 설정에 따라 Invalid Host header 에러가 발생할 수도 있다는 것입니다.

 

현재 이 글은 프로젝트가 끝난 뒤에 작성하고 있는데, 그 때 사용했던 EC2와 다른 환경에서 테스트를 해보니 현재 EC2에서는 Invalid Host header 에러가 발생하지 않습니다.

 

아래 시물레이션은 배포했을 때 문제가 생기던 상황을 시물레이션 한 것입니다.

📦 시물레이션

먼저 아무것도 깔려있지 않은 EC2라고 가정하겠습니다.

먼저 NVM을 설치해줍니다.

 

1. NVM 설치

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

2. NVM 활성화

. ~/.nvm/nvm.sh

3. Node 설치

nvm install node

 

위와 같이 node가 잘 설치됐다면 npx create-react-app react-app 명령어를 통해서 react-app을 생성해줍니다.

proxy에 서버를 명시하면 invalid host header가 뜨고, proxy에 서버를 명시하지 않으면 정상적으로 작동합니다.

📦 해결

처음에 구글링을 해보았을 때 아래 글과 같이 webpack.config.js 에 있는 파일을 수정해서 해결하는 방법을 고안했습니다.

( https://bytrustu.tistory.com/73 )

cf) 🔖 webpack.config.js 파일은 node_modules/react-scripts/config/webpackDevServer.config.js 에 있습니다.

 

webpack.config.js 안에 있는 disableHostCheck 속성을 true로 주면 해결이 된다는 것이었습니다.

그런데, webpack 버전이 바뀌었는지, 해당 파일이 블로그들에 나와있는 글과 달랐습니다.

 

저의 경우 react와 webpack에 관해 거의 잘 알지 못했기 때문에 무엇이 어떻게 다른지 숙지하기도 힘들었습니다.

그래서 여러 시도와 고민을 해보다가 react와 webpack 안에서 해결을 하려고 하지 말고, nginx를 통해 해결을 해보자 생각했습니다.

어차피 요청은 proxy server로 nginx를 통해 요청이 왔다갔다 하므로 3000번 포트로 직접 접근해서 요청을 받을 일은 없었기 때문입니다.

 

해결방법은 아래와 같습니다.

  • react로 빌드 파일을 생성한다.
  • 80번 포트로 들어왔을 때, build 된 react 파일을 실행하도록 한다.

react - nginx 관련 설정은 아래 사이트를 참조하였습니다.

( https://codechacha.com/ko/deploy-react-with-nginx/ )

 

server {
   listen 3000;
   location / {
      root /home/ubuntu/app-deploy/build;
      index index.html;
      try_files $uri $uri/ /index.html;
   }
}

📦 후기

저의 경우 해당 프로젝트에서 Backend를 맡았지만, 배포를 하는 과정에서 프론트 쪽 관련 에러가 생겨서 참으로 난감했습니다.

프로젝트 기간이 7주 였는데, 저는 거의 1주일내내 이 에러를 붙잡고 있었던 것 같습니다.

( 또한 Jenkins와 Gitlab 관련 에러도 계속 생겨서 매우 난감했습니다 ... 😭 )

 

특히 이 Invalid Host header관련 에러는 SSAFY내에서 프로젝트를 관리해주시는 코치님들에게 여쭤보았지만 코치님들도 처음 보는 에러라서 해결에 직접적인 도움이 되지는 못하였습니다. ( 간접적으로는 많은 도움을 받았습니다. )

 

확실히 왜 Devops는 신입을 뽑지 않는 지, 그리고 Frontend와 Backend 폭 넓은 지식을 갖고 있어야 Devops를 할 때 능통할 수 있겠다라는 생각이 많이 든 프로젝트였습니다.

 

긴글 읽어주셔서 감사합니다!


reference

🔖 Domain - Origin 차이
( https://velog.io/@josworks27/CORS-%EA%B8%B0%EC%B4%88-%EA%B0%9C%EB%85%90 )

🔖 NVM 설치
( https://jsikim1.tistory.com/176 )

🔖 CORS - SOP
( https://velog.io/@jesop/SOP%EC%99%80-CORS )
( https://xiubindev.tistory.com/115 )

🔖 invalid host header error
( https://bytrustu.tistory.com/73 )
( https://medium.com/@AvinashBlaze/what-is-this-invalid-host-header-error-9cd760ae6d16 )

 

 

댓글