Mixed Content 에러를 알아보고 해결했습니다.

발생한 문제

연구실 업무로 개발중인 설문 웹페이지에서 마지막에 설문 결과를 서버로 보내는 부분이 아래의 에러를 뿜으며 동작하지 않는 문제가 발생했습니다.

Mixed Content: The page at 'https://goodrider-interview-web.vercel.app/submitted' was loaded over HTTPS, but requested an insecure resource 'http://geodb.uos.ac.kr/api/driver/post/survey'. This request has been blocked; the content must be served over HTTPS.

/submitted 경로에서 POST 요청을 HTTP 프로토콜로 열려있는 백엔드 서버에 날리는 과정이었는데요! 해석해보면 이런 내용인거죠.

요청을 날리는 웹은 HTTPS로 로드되고 있는데, 요청을 받는 웹은 보안이 취약한 HTTP 프로토콜로 이뤄져 있어서 내가 막아줬어!

보안을 걱정해주는건 고마운데, 곤란한 상황이죠. 백엔드의 API를 HTTPS로 제공하면 베스트겠지만 서버를 건드릴 수 없는 경우에는 어떻게 해결할 수 있을까요?

Mixed Content가 뭐야?

우선 Mixed Content가 뭔지부터 제대로 알고 가는게 첫 단계입니다.

MDN 문서

간단하게 말하면 HTTPS로 제공되는 웹페이지에서 HTTP 프로토콜로 받은 컨텐츠를 포함하고 있는 경우 이 컨텐츠를 Mixed Content라고 부릅니다. 이 경우 웹페이지는 부분적으로만 암호화돼있는 상태인거고, 결국 암호화되지 않은 부분은 미들맨 공격(man-in-the-middle attack)에 노출됩니다.

HTTP와 HTTPS의 차이를 더 확실하게 알고 있다면 깊은 이해가 가능할 것 같아요. 간단하게 설명하면 HTTPS는 패킷으로 데이터를 주고받는 프로토콜인 HTTP에 중간에 패킷을 가로채 데이터를 가져가거나 수정하지 못하게 암호화 계층(TLS)을 추가한 프로토콜입니다.

어떻게 해결할까? - 프록시로 접근해보자.

다행히도 저는 이 오류를 접하기 전에 '프록시 서버(Proxy Server)'라는 개념을 알고 있었습니다. 프록시 서버는 서버와 클라이언트 사이에 위치하면서 클라이언트 대신 서버와 통신해 응답을 돌려주는 중간 서버입니다.

CORS 문제, 보안상 이유 등으로 프록시 서버를 사용할 수 있습니다. 프록시 서버는 서버에 요청을 날릴 때 클라이언트에 관한 그 어떤 데이터도 제공하지 않기 때문입니다.

설문지 웹페이지는 Next.js로 개발됐기 때문에, Next.js 웹 서버 자체를 프록시 서버로 활용해 문제를 해결할 수 있을 것이라고 생각했습니다. 찾아보니 아래의 방법으로 프록시를 설정할 수 있다고 합니다.

next.config.js

module.exports = {
  rewrites: () => [
    {
      source: "/post",
      destination: "http://geodb.uos.ac.kr/api/driver/post/survey",
    },
  ],
}
module.exports = {
  rewrites: () => [
    {
      source: "/post",
      destination: "http://geodb.uos.ac.kr/api/driver/post/survey",
    },
  ],
}

next.config.js에 요청 path와 연결해야 할 URL을 이런 식으로 넣으면 됩니다. rewrite()라는 함수로 넣기 때문에 유동적으로 바꿀수도 있습니다.

위 설정을 통해 클라이언트는 https://goodrider-interview-web.vercel.app/api/post 라는 URL로 http://geodb.uos.ac.kr/api/driver/post/survey 라는 엔드포인트에 접근할 수 있게 됐습니다.