Netlify에서 HTTPS -> HTTP 통신 해결 과정

Ji-Heon Park·2023년 3월 31일
6

공유책방

목록 보기
2/2
프로젝트 이름프로젝트 개요진행날짜소스코드
공유책방중고 도서 공유 플랫폼2022.09-2022.12https://github.com/gong-you-bookstore/client

배경

공유책방은 마이크로서비스 아키텍처(Microservices Architecture)를 채택하여 클라이언트, 메인서버와 추천서버로 나뉘어져 있습니다. 시스템 아키텍쳐는 다음과 같습니다.

공유책방의 프론트엔드는 Netlify를 사용해 배포하였습니다. Netlify는 정적인 웹을 무료로 배포하여주는 웹서비스이며 무료라는 점과 Github와 연동하여 간편한 배포가 가능하다는 장점을 가지고 있어 채택하였습니다. 백엔드 메인서버와 추천 시스템 인퍼런스 서버는 AWS EC2로 담당 팀원분께서 배포하셨습니다.

문제

Netlify 기본적으로 HTTPS를 사용하는 반면, 서버는 SSL 인증을 받지 않았기에 HTTP 방식이었습니다. 개발 단계의 로컬 환경에서는 문제가 없었으나, HTTPS와 HTTP의 통신을 금지하는 네트워크 정책으로인해 배포환경에서 프론트와 서버간 통신을 못하는 문제가 있었습니다.

HTTP vs HTTPS ?

  • HTTP는 서버/클라이언트 모델을 따라 데이터를 주고받기 위한 프로토콜, HTTPS는 HTTP에 데이터 암호화가 추가된 프로토콜
  • HTTP는 암호화가 추가되지 않았기 때문에 보안에 취약한 반면, HTTPS는 안전하게 데이터를 주고받을 수 있음
  • HTTPS는 인증서를 발급하고 유지하는데에 추가 비용이 발생한다.
  • 개인정보와 같은 민감한 데이터를 주고 받는다면 HTTPS를 이용해야 하지만, 단순 정보 조회 같은 사이트는 HTTP를 적용하면 된다.

HTTPS HTTP간 통신 문제가 있는 경우 일반적으로 다음과 같은 대처 방법이 있습니다.

문제상황 1: 클라이언트(HTTP) -> 서버(HTTPS)

클라이언트 헤더에 아래 메타태그 추가합니다. 클라이언트에서 보내는 모든 요청이 https로 바뀌어서 문제 해결됩니다. 하지만 우리 서비스의 경우 HTTPS → HTTP 였기에 해당 상황이 아닙니다.

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

문제상황 2: 클라이언트(HTTPS) -> 서버(HTTP)

해결법 1: 서버에 ssl인증 받아서 서버를 https로 바꾸기

서버에 SSL인증을 받아 HTTPS로 바꿔야 합니다. 하지만 공유책방은 서비스의 메인기능을 담당하는 메인서버와 책 추천을 위한 추천시스템 서버 두가지 서버와 통신합니다. + 대학생들끼리 졸업작품으로 진행하는 프로젝트라 비용 문제가 부담스러웠습니다.

해결법 2: 클라이언트 배포를 바꾸기

Netlify 공식 답변에 따르면 HTTPS를 HTTP로 낮추는 것은 불가능합니다. 즉 Netlify 선택지를 포기하고 다른 방법을 사용해 배포해야합니다. 하지만 공유책방의 경우 사용자간 거래가 이루어지는 플랫폼이기에 보안이 중요하여 보류하였습니다.

해결

저와 같은 상황에 있는 사용자들의 질문에 Netlify 측 공식 답변은 서버에 SSL인증을 받는 수 밖에 없다 하였습니다. 하지만 위에 적은 비용적인 문제로 인해 서버 담당자분께서 이를 꺼려하셨습니다. 좀 더 방법을 찾던 중 Netlify 공식문서에서 해답을 찾았습니다. 리다이렉트 경로를 설정하여 모든 요청을 브라우저에서 추가로 연결하지 않고, CDN서버에서 바로 프록시 시키는 방식을 사용해 서버와 통신을 가능하게 하는 것입니다.

소스코드

public/_redirects에 아래의 라인을 넣습니다.

/api/* http://{your server URL}/:splat 200

클라이언트에서 요청을 보내는 곳은 다음과 같이 작성합니다.

const host = window.location.hostname === "localhost" 
  ? 'http://{your server URL}'
  : "api";

export const apiClient = axios.create({
  baseURL: host,
});

로컬호스트일때는 기존 서버 url로 요청을 합니다. Netlify 배포 환경에서는 baseURL에 위에서 지정한 api 를 넣습니다. 이렇게 public/_redirects에서 지정한 문자열을 넣으면 CDN서버에서 프록시 시켜 요청을 정상적으로 보내집니다.

e.g. GET http://{your server URL}/books -> GET api/books

공식문서 내용

Proxy to another service

Similar to how you can rewrite paths like / to /index.html, you can also set up rules to let parts of your site proxy to external services. Let’s say you need to communicate from a single-page app with an API on https://api.example.com that doesn’t support CORS requests. The following rule will let you use /api/ from your JavaScript client: /api/ https://api.example.com/:splat 200
Now all requests to /api/... will be proxied through to https://api.example.com straight from our CDN servers without an additional connection from the browser. If the API supports standard HTTP caching mechanisms like ETags or Last-Modified headers, the responses will even get cached by our CDN nodes.
출처: https://docs.netlify.com/

profile
Frontend Developer | 기록되지 않은 것은 기억되지 않는다

4개의 댓글

comment-user-thumbnail
2023년 6월 6일

고생중이었는데 덕분에 해결되었습니다😂 감사합니다!

답글 달기
comment-user-thumbnail
2023년 11월 21일

안녕하세요! 저도 같은 문제로 배포를 못하고 있네요 ㅠㅠ 감사합니다. 알려주신 대로 보면 public 폴더아래 _redirects 파일을 만들면 되는건가요? 그리고 나머지 부분은 제가 API 서버를 설정한 곳에 말씀해주시는 것과 같이 수정하면 되는건지요?! ㅠㅠ 계속 에러가 나서 답답한 마음에 댓글 남깁니다! 감사합니다~

1개의 답글
comment-user-thumbnail
2023년 12월 17일

안녕하세요! api 주소를 이용해서 통신을 시도하는 모든 페이지에 const host 코드를 작성하면 되는 것일까요?

답글 달기