본문 바로가기
카테고리 없음

클라이언트 사이드 말고, 서버 사이드로도 mixed content 에러가 뜰까?

by klm hyeon woo 2025. 5. 2.

목차

· 브라우저에서 mixed content가 발생하는 이유는 뭘까?

· mixed content의 종류

· Next 서버 사이드에서는 왜 에러가 발생하지 않을까?


https 환경에서 http 환경의 api에 통신을 할 때 많이 볼 수 있는 mixed content 에러를 많이 보셨을 것 같아요.

서버리스 환경의 프로덕트에서 DB와 다양한 기능들을 추가하기 위해 서버 개발자들과 협업 하는 과정에서 클라이언트 사이드 환경에서는 mixed content를 경험해보았지만 Next를 사용하다보니 서버에서 데이터 패칭을 할 때는 mixed content가 발생을 할까? 에 대한 궁금점이 들었어요. 그래서 궁금점을 조금 해소해보고자 이렇게 포스팅을 하게 되었답니다.

 

브라우저에서 mixed content가 발생하는 이유는 뭘까?

mixed content는 웹 페이지가 https(보안 연결)로 로드되었는데, 그 안에서 http(비보안 연결) 리소스를 로드하려고 할 때 발생하는 문제를 의미해요. `https://my-website.com`과 같은 브라우저 주소 창에서 `http`와 같은 안전하지 않은 비보안 콘텐츠를 가져오고자 했을 때 브라우저는 보안 위험으로 간주하여 차단하거나 경고메세지를 띄워요. 만약 https 페이지 안에서 http 리소르르 허용하게 된다면, html 본문은 암호화되지만 이미지, js, css, api 데이터는 암호화되지 않은 http 경로로 유출될 수 있고 중간자 공격(Man-in-the-Middle Attack)을 통해 탈취당할 수 있어요.

mixed content 의 종류

mixed content는 능동적인 부분과 수동적인 부분의 두 종류를 가지고 있어요.

  • active mixed content (능동적)
    • <script>, <iframe>, <link rel="stylesheet"> 등 코드 실행에 관여하는 리소스를 의미해요
    • 이때 브라우저는 자동으로 차단을 하게 돼요.
  • passive mixed content (수동적)
    • <img>, <audio>, <video> 등 단순 표시용 리소스
    • 이때 브라우저는 경고를 발생시켜요.

Next 서버 사이드에서는 왜 에러가 발생하지 않을까?

getServerSideProps, getStaticProps, API routes, middleware 같은 함수들은 브라우저가 아닌 node.js 서버에서 호출이 돼요.

Next 서버 (node.js) > HTTP API 요청 > 서버 내부 요청

서버와 서버끼리 통신을 하게 되는 거죠, 서버는 브라우저의 보안 정책을 따르지 않기 때문에 mixed content가 적용되지 않아요.

클라이언트가 API에 직접 접근을 하는 것이 아니라 Next 서버가 API에서 데이터를 가져와서 클라이언트에 HTTPS로 전달하기 때문에 브라우저 입장에서는 "이미 안전한 HTTPS로 받은 데이터"라고 인식을 하게되는 꼴이에요.

export async function getServerSideProps() {
  const res = await fetch('http://insecure-api.com/data');
  const data = await res.json();

  return { props: { data } };
}

export default function Home({ data }) {
  return <pre>{JSON.stringify(data, null, 2)}</pre>;
}

위와 같이 Next 서버 자체에서 데이터 패칭을 하여 클라이언트로 데이터를 전달받는다면 mixed contents는 발생하지 않겠지만, 아래 코드에서는 또 다르다는 것을 위에 기재한 내용들을 바탕으로 유추할 수 있을 것 같아요.

useEffect(() => {
  fetch('http://insecure-api.com/data') // mixed content!!
    .then((res) => res.json())
    .then(setData);
}, []);

 

댓글