UX와 불법 공유 방어 사이의 타협

그림책 서비스를 만들면서 가장 오래 고민한 문제 중 하나는 “로그인하지 않은 방문자에게 어디까지 보여줄 것인가”였다.

콘텐츠를 보여주지 않으면 가입 전환이 어렵다. 반대로 원본 이미지를 너무 쉽게 보여주면, 한 번의 캡처나 다운로드만으로 콘텐츠가 외부로 퍼질 수 있다.

이 문제는 완벽한 보안 기능으로 해결되지 않는다. 화면에 보이는 이미지는 어떤 방식으로든 캡처할 수 있기 때문이다. 결국 현실적인 목표는 “불법 공유를 완전히 막는 것”이 아니라, 서비스를 이용하는 사람의 경험을 해치지 않으면서 무단 재사용의 비용과 심리적 장벽을 높이는 것이다.

로그인 전에 책을 읽어볼 수 있어야 한다

그림책은 구매 전환 전에 직접 경험해야 하는 콘텐츠다.

상품 설명과 표지만으로는 책의 분위기, 그림의 질감, 문장의 호흡을 충분히 전달하기 어렵다. 특히 부모가 아이와 함께 읽을 책을 고르는 서비스라면, 방문자가 로그인부터 해야 하는 구조는 첫 화면에서 이탈을 만들기 쉽다.

그래서 무료 열람이 허용된 책은 게스트도 바로 읽을 수 있도록 했다. 로그인이나 회원가입을 강제하지 않고, 먼저 책을 경험하게 하는 방식이다.

이 선택은 UX 측면에서 분명한 장점이 있다.

  • 가입 전에 콘텐츠 품질을 확인할 수 있다.

  • 아이와 함께 바로 읽어볼 수 있다.

  • 로그인 화면으로 이동했다가 다시 책을 찾아야 하는 불편이 없다.

  • “무엇을 파는 서비스인지”를 설명보다 경험으로 전달할 수 있다.

하지만 게스트 열람에는 곧바로 보안 문제가 따라온다. 원본 이미지를 그대로 제공하면, 무료 미리보기와 원본 배포의 경계가 흐려진다.

워터마크는 차단 장치가 아니라 책임 표시다

현재 워터마크는 이미지를 아예 가리는 방식이 아니다. 페이지의 감상 경험을 유지할 수 있도록 이미지 위에 작고 반투명한 문구를 합성한다.

회원에게는 다음과 같은 정보가 들어간다.

UID:123  2026-10-20

게스트에게는 계정이 없기 때문에 다음처럼 표시한다.

GUEST  2026-10-20

이 표시는 강력한 DRM이 아니다. 스크린 캡처를 막지도 않고, 워터마크를 잘라내는 편집을 완전히 방지하지도 못한다.

그럼에도 의미가 있는 이유는 세 가지다.

첫째, 캡처된 이미지가 원본 파일처럼 보이지 않는다.
둘째, 이미지가 서비스 화면에서 가져왔다는 흔적이 남는다.
셋째, 회원 이미지에는 계정 식별자가 남기 때문에 무단 공유에 대한 책임성이 높아진다.

즉 워터마크의 역할은 “복사를 불가능하게 만드는 것”이 아니라 “복사와 공유를 가볍게 생각하지 않도록 만드는 것”에 가깝다.

게스트에게 UID를 넣을 수 없는 이유

회원에게는 UID를 표시할 수 있지만, 게스트에게는 추적할 계정이 없다.

여기서 억지로 브라우저 쿠키나 IP 주소를 표시하는 방법을 택할 수도 있다. 하지만 그런 정보는 사용자에게 설명하기 어렵고, 정확한 식별자라고 보기도 어렵다. 여러 사람이 같은 네트워크를 사용할 수도 있고, 쿠키는 삭제될 수 있으며, IP는 개인을 직접 특정하는 값도 아니다.

그래서 게스트에게는 정직하게 GUEST라는 상태만 표시하고 날짜를 함께 남긴다.

이것은 추적을 가장하는 것보다 낫다. 보안 기능은 실제로 할 수 있는 일을 정확하게 약속해야 하기 때문이다.

워터마크가 너무 눈에 띄면 UX가 무너진다

보안만 생각하면 워터마크를 크게, 진하게, 화면 중앙에 반복해서 넣고 싶어진다. 하지만 그림책에서는 그 순간 콘텐츠의 감정이 깨진다.

아이와 함께 보는 페이지에 커다란 경고 문구가 반복되면 독자는 보호받는다는 느낌보다 감시받는다는 느낌을 받을 수 있다. 그림의 여백과 구성도 훼손된다.

그래서 현재 방식은 다음과 같은 타협을 택한다.

  • 페이지 전체를 덮지 않는다.

  • 모서리에 작게 배치한다.

  • 반투명하게 표시한다.

  • 원본 이미지를 별도 파일로 내려주지 않는다.

  • 회원과 게스트의 상태를 서로 다른 문구로 구분한다.

이 방식의 핵심은 워터마크를 콘텐츠보다 앞세우지 않는 것이다. 워터마크는 존재감을 가져야 하지만, 독서 경험의 주인공이 되어서는 안 된다.

이미지 보호는 서버에서 처리해야 한다

브라우저에서 JavaScript로 우클릭을 막거나 단축키를 차단하는 방식은 보조 수단일 뿐이다. 개발자 도구나 네트워크 요청을 확인할 수 있는 사용자는 쉽게 우회할 수 있다.

따라서 중요한 보호는 서버에서 처리해야 한다.

이미지 요청이 들어오면 서버가 원본 파일을 바로 내보내지 않고, 워터마크가 합성된 JPEG를 만들어 응답한다. 동일한 사용자와 동일한 이미지에 대해서는 날짜를 포함한 캐시 키를 사용해 반복 합성 비용도 줄인다.

이 구조는 다음과 같은 책임을 분리한다.

  1. 열람 권한은 컨트롤러와 서비스가 판단한다.

  2. 어떤 식별자를 표시할지는 워터마크 서비스가 결정한다.

  3. 원본 이미지와 합성 이미지는 서버 내부에서 처리한다.

  4. 브라우저에는 최종 결과물만 전달한다.

이렇게 하면 화면 코드에 보안 로직이 흩어지지 않고, 회원·게스트 정책도 한 곳에서 관리할 수 있다.

가장 중요한 것은 실패할 때의 동작이다

워터마크 시스템에서 특히 조심해야 할 부분은 이미지 처리 실패다.

이미지 라이브러리가 파일을 읽지 못하거나, 폰트가 없거나, 특정 이미지 형식을 처리하지 못할 수 있다. 이때 시스템이 원본 이미지를 그대로 반환하면, 평소에는 잘 작동하던 보호 장치가 특정 조건에서 조용히 무력화된다.

현재 구조에서도 이미지 합성에 실패하면 원본 파일을 반환하는 경로가 존재한다. 이것은 서비스 중단을 피하는 데는 유리하지만, 보안 관점에서는 중요한 타협점이다.

따라서 운영 환경에서는 최소한 다음을 점검해야 한다.

  • 이미지 합성 실패를 로그로 남길 것

  • 원본 반환이 발생했는지 모니터링할 것

  • 지원하지 않는 형식은 사전에 변환할 것

  • 폰트와 GD 등 필수 처리 환경을 배포 단계에서 검사할 것

  • 실패 시 원본 대신 제한된 미리보기 이미지를 반환하는 정책을 검토할 것

보안 기능은 성공할 때보다 실패할 때의 기본값이 더 중요하다. “처리할 수 없으니 원본을 보여준다”는 기본값은 UX에는 친절하지만, 보호 목적과는 충돌한다.

워터마크만으로는 충분하지 않다

워터마크는 여러 방어 계층 중 하나일 뿐이다.

함께 고려해야 할 요소는 다음과 같다.

  • 원본 저장 경로를 웹 루트와 분리하기

  • 이미지 URL에 예측하기 어려운 식별자 사용하기

  • 열람 권한을 서버에서 매 요청 검증하기

  • 구매·구독 만료 시 접근 권한 즉시 회수하기

  • 비정상적인 짧은 시간 내 반복 요청 감지하기

  • 페이지 이미지의 해상도와 제공 범위를 정책화하기

  • 캡처·공유에 대한 서비스 안내를 명확히 표시하기

다만 이 모든 장치를 과도하게 적용하면 정상 사용자가 먼저 불편해진다. 토큰을 너무 자주 갱신하면 페이지 넘김이 느려지고, 해상도를 지나치게 낮추면 독서 경험이 나빠지며, 인증을 매번 강제하면 서비스가 불안정하게 느껴진다.

결국 방어는 한 가지 기능의 강도가 아니라, 여러 작은 장치가 만드는 전체적인 마찰의 균형으로 설계해야 한다.

좋은 보안 UX는 사용자를 의심하지 않는다

게스트 열람을 허용하면서 워터마크를 넣는 결정은 타협처럼 보인다. 하지만 실제로는 서비스가 사용자에게 보내는 메시지의 균형을 잡는 일이다.

“로그인하지 않으면 아무것도 보여주지 않겠습니다”라고 말하는 대신,

“먼저 충분히 경험해보세요. 다만 이 콘텐츠는 보호되고 있습니다”라고 말하는 것이다.

이때 워터마크는 사용자를 범죄자로 취급하는 경고문이 아니라, 콘텐츠의 출처와 이용 조건을 조용히 알려주는 표식이어야 한다.

그림책 서비스에서 가장 중요한 것은 독자가 페이지를 넘기는 흐름이다. 보안은 그 흐름을 끊지 않으면서 콘텐츠의 가치를 지키는 방향으로 작동해야 한다.

완벽한 차단은 현실적으로 어렵다. 대신 우리는 다음과 같은 기준을 세울 수 있다.

  • 가입 전에는 충분히 경험할 수 있게 한다.

  • 원본 파일은 그대로 노출하지 않는다.

  • 캡처되더라도 출처 흔적이 남게 한다.

  • 회원 콘텐츠에는 식별 가능한 책임성을 부여한다.

  • 보호 기능이 실패했을 때를 모니터링한다.

  • 정상 사용자의 독서 경험을 보안보다 불필요하게 희생하지 않는다.

결국 좋은 워터마크는 눈에 잘 띄는 워터마크가 아니다. 콘텐츠를 망치지 않으면서도, 그 이미지가 아무런 제약 없이 떠도는 원본은 아니라는 사실을 남기는 워터마크다.ㅁㅂㄴㅈㅂㅂㅂㅂㅂㅂㅂㅂㅂㅂㅂㅂㅈㅁㅌ