2026-09-11 11:00에 작성됨

기술 스택

상정인사이드 기술 스택

상정인사이드의 기술 스택과 보안, UX/UI 관점에서의 기술을 자세히 알려드릴게요.

상정인사이드 기술 스택


포트폴리오에 있는 '자세히 보기' 팝업만으로는 상정인사이드라는 프로젝트에 어떤 기술이 들어가 있는지 온전히 전달하기가 아무래도 어려웠어요. 몇 줄짜리 요약으로는 왜 이런 구조를 선택했는지, 어떤 고민 끝에 이 기능을 만들었는지까지는 담을 수가 없더라고요. 그래서 이번 글에서는 팝업에 못다 적은 이야기까지 포함해서, 상정인사이드의 기술 스택을 처음부터 끝까지 자세히 풀어보려고 해요.


전체 구조, 한눈에 보기


상정인사이드는 서버 하나로 모든 걸 처리하는 구조가 아니에요. 역할이 명확히 다른 두 개의 서버로 나눠서 운영하고 있어요.


  • 메인 서버 — 게시판, 댓글, 관리자 패널, 그리고 앞으로 설명드릴 각종 보안 로직까지, 서비스의 핵심 기능을 전담해요.
  • SEO 이미지 서버 — 오픈그래프(Open Graph) 이미지를 실시간으로 생성하는 역할을 맡고 있어요. 누군가 상정인사이드 링크를 공유했을 때, 클릭하기도 전에 미리보기 이미지만 보고도 "아, 이런 기능이 있는 페이지구나"를 한눈에 알 수 있도록 도와주는 서버예요.


두 서버 모두 PM2로 프로세스를 관리하고 있고, 실제 서빙은 WSGI 서버를 통해 이뤄지고 있어요. 그리고 조금 특이한 부분이라면, 이 모든 서버가 클라우드가 아니라 제 집 안에서 직접 돌아가는 홈 서버라는 점이에요. 트래픽이 몰릴 때마다 신경이 곤두서는 건 어쩔 수 없지만, 그만큼 서버 하나하나를 제 손으로 직접 다뤄볼 수 있다는 점에서는 오히려 더 애착이 가는 부분이기도 해요.


포트폴리오의 자세히 보기 팝업을 이미 보신 분들이라면 짐작하셨겠지만, 상정인사이드는 철저히 '익명'을 중심에 두고 개발한 프로젝트예요. 그래서 사용자 편의 기능을 화려하게 늘리는 것보다는, 보안과 어뷰징 방지 쪽에 훨씬 더 많은 공을 들였어요.


보안 · 어뷰징 방지 — 가장 많은 시간을 쏟은 영역


사실 이 프로젝트에서 제가 가장 많은 시간을 쏟은 부분을 하나만 꼽으라면, 망설임 없이 이 보안 영역을 꼽을 거예요.


저는 처음부터 '로그인'이라는 과정 자체를 없애고 싶었어요. 회원가입도, 비밀번호 찾기도, 이메일 인증도 없이 그냥 접속해서 바로 글을 쓰고 댓글을 달 수 있는 게 상정인사이드가 지향하는 방향이었거든요. 문제는 로그인이 없다는 건 곧 서버가 사용자를 구분할 다른 방법을 스스로 마련해야 한다는 뜻이라는 거였어요. 그래서 다음과 같은 방식으로 사용자를 식별하도록 설계했어요.


  • 브라우저 지문(fingerprint) 기술을 활용해서 사용자의 해상도, 브라우저 종류, 대략적인 위치, 접속 시간, 디바이스 정보 등을 조합한 식별 코드를 만들어 저장해요.
  • ISP 기준 /24 대역의 IP에서 발생한 요청은 같은 사용자의 요청일 가능성이 높다고 보고 하나로 묶어요. 이렇게 하면 사용자가 와이파이를 껐다 켜거나 모뎀을 재시작해서 IP가 바뀌더라도, 같은 사람으로 인식할 수 있어요.


그런데 익명 커뮤니티라는 특성상, 이것만으로는 부족했어요. 도배, 어뷰징, VPN을 통한 우회 접속까지 대응하려면 훨씬 더 촘촘한 방어선이 필요했거든요.



VPN · 프록시 · Tor 탐지


  • Tor 공식 Exit Node 리스트(check.torproject.org)를 1시간마다 갱신해서, 최신 목록을 기준으로 접속 차단 리스트를 계속 최신 상태로 유지하고 있어요.
  • SoftEther VPN을 막기 위해서는 SoftEther 서버 목록을 10분마다 동기화해서 차단 리스트에 반영하고 있어요.
  • proxycheck.io API를 연동해서 실시간으로 VPN·프록시·호스팅 서버발 IP인지를 판별해요. 이때 계산되는 risk score가 80점을 넘어가면 별도의 확인 없이 자동으로 차단하도록 만들어 뒀어요.


다만 이렇게 IP만 놓고 무작정 차단하다 보면, 정작 걸러내야 할 대상이 아니라 Google이나 AWS, 네이버 같은 곳의 정상적인 검색 색인 봇까지 함께 막혀버릴 위험이 있더라고요. 그래서 모든 차단 로직을 거치기 전에 host 명령어로 역방향 DNS(PTR) 조회를 자동으로 먼저 수행하고, 신뢰할 수 있는 호스트라고 판단되면 화이트리스트로 분류해서 예외 처리하도록 만들었어요.



사람인지 두 번 확인하기


Cloudflare Turnstile을 사이트 전반에 적용해서 지속적으로 "이 사용자가 정말 사람인지"를 확인하고 있고, 여기에 더해 Google reCAPTCHA v3를 게시물 등록과 댓글 등록 시점에 한 번 더 적용해서 2차로 검증하도록 이중 장치를 만들어 뒀어요.



응답 헤더와 접근 제어


모든 응답에는 X-Frame-Options, Content-Security-Policy, Referrer-Policy, Cross-Origin-Resource-Policy, X-Content-Type-Options 같은 보안 헤더를 기본으로 적용했고, Origin 기반 접근 제어도 함께 도입해서 허용되지 않은 출처에서의 요청을 걸러내도록 했어요.



그 밖의 방어 장치들


클라이언트 단에서 브라우저 조작이 감지되는 경우에는 자동으로 접속을 차단하도록 만들었어요. 상정인사이드는 여러 최신 Web API와 기술을 적극적으로 사용하는 서비스이기 때문에, 애초에 정상적으로 동작할 수 있는 브라우저 환경에서만 접속이 가능하도록 설계한 셈이에요.


그리고 이 모든 검증은 처음 접속할 때 한 번만 이뤄지는 게 아니에요. 요청이 들어올 때마다 저마다의 의심 점수(suspicion score) 를 부여하고, 이 점수가 특정 기준을 넘어서면 그 클라이언트에 대해 지금까지 쌓인 모든 정보를 바탕으로 훨씬 더 정밀한 2차 보안 검증을 거치도록 설계했어요. 이 과정은 전부 서버 내부에서 조용히 처리되기 때문에, 사용자 입장에서는 서버가 어떤 기준으로 판단하고 있는지 패턴을 파악하기가 쉽지 않아요.




사용자가 직접 체감할 수 있는 UX · UI


지금까지는 눈에 보이지 않는 곳에서 벌어지는 이야기였다면, 이제부터는 실제로 사용자가 화면을 통해 마주하게 되는 기능들을 소개해 드릴게요.



1. 메인 페이지와 첫 방문자를 위한 랜딩 페이지


① 첫 방문자 전용 랜딩 페이지



개발 초기에 Microsoft Clarity로 사용자 행동을 분석해 봤는데, 처음 들어온 사용자에게 다짜고짜 서비스 화면부터 보여주면 이탈률이 확 올라간다는 걸 데이터로 확인했어요. 그래서 첫 방문자를 위한 별도의 안내용 랜딩 페이지를 새로 만들었어요.



② 같은 경로, 다른 화면
메인 루트로 접속하더라도 서버 단에서 쿠키 기반의 방문 여부를 체크해서, 서비스 페이지와 랜딩 페이지를 같은 경로 안에서 자연스럽게 나눠 보여주도록 만들었어요. 이 과정에서 commu.world/?stpg=1처럼 특정 쿼리를 붙이면, 이미 방문했던 사용자도 원할 때 언제든 랜딩 페이지를 다시 확인할 수 있게 설계해 뒀어요.



③ 로딩 화면도 그냥 넘기지 않기



메인 루트의 로딩 화면에서는 브랜드 이미지가 더 또렷하게 드러나도록 불필요한 시각 요소를 걷어내고, 훨씬 깔끔하고 정돈된 형태로 다시 다듬었어요. 또 로딩이 평균 시간보다 오래 걸리면 자동으로 캐시를 초기화하고 새로고침을 시도하도록 만들었고, 그래도 해결되지 않는다면 "로딩이 지연되고 있습니다. 쿠키 삭제 후 새로고침을 시도해 주세요."라는 안내 문구가 뜨도록 처리했어요.



④ 텍스트 하나에도 신경 쓴 Hero 섹션
랜딩 페이지 Hero 섹션의 "로그인 없이, 바로 익명." 문구 중 '로그인' 자리에는 여러 단어가 순차적으로 바뀌는 로테이션 애니메이션을 넣었어요. 이때 텍스트 길이가 바뀌어도 어색하지 않도록 부드럽게 확장·축소되는 전환 효과를 함께 적용해서 시각적인 이질감을 최소화했고, 페이지 전반에는 스크롤에 반응하는 인터랙티브 애니메이션을 넣어서 조금 더 몰입감 있는 경험이 되도록 신경 썼어요.



⑤ 댓글이 많아질수록 편해지는 화면



댓글이 기본 설정인 5개를 넘어가면 "댓글 N개 더보기" 형태로 자동으로 접히도록 만들었어요. 댓글이 많이 달린 글 아래로 다음 게시물을 보려면 스크롤을 한참 내려야 했던 불편함을 해결하고 싶어서 만든 기능이에요. 그리고 "댓글 N개 더보기"를 눌러서 펼쳤던 게시물은 브라우저 캐시에 실시간으로 기록해서, 새로고침을 하더라도 펼쳐놨던 상태가 다시 접히지 않도록 만들었어요.



⑥ 부적절한 표현은 자동으로 가려주는 검열 기능
부적절한 단어가 감지되면 자동으로 * 처리해서 가려주는 검열 기능도 함께 넣었어요.



⑦ 새로고침 없이 실시간으로 반영되는 정보
댓글, 게시물, 추천 · 비추천 같은 정보들이 새로고침 없이도 자동으로 반영되는 '정보 실시간 반영' 기능을 구현했어요.



⑧ 처음 써도 헤매지 않게, 빠른 설정



"저사양 모드", "실시간 모드", "일반 모드"처럼 미리 구성해 둔 빠른 설정을 통해 처음 사용하는 분들도 어렵지 않게 원하는 환경으로 바로 전환할 수 있도록 했어요. 또 iOS나 Mac 환경의 사파리 브라우저로 접속했을 때 이미지 · 링크 파싱 기능이 켜져 있으면 디자인이 깨지는 현상이 있었는데, 이 경우에는 자동으로 안내창(alert)을 띄운 뒤 해당 기능을 비활성화하도록 처리했어요.



⑨ 공지사항, 스크롤 없이 바로 확인



메인 서비스 페이지 헤더 바로 위에 공지사항과 최신 업데이트 릴리즈를 자동으로 노출하도록 만들었어요. 덕분에 사용자가 Footer까지 힘들게 스크롤을 내리지 않아도 최근 업데이트 내역을 곧바로 확인할 수 있어요.



⑩ 꼭 필요한 정보는 Footer 위에



"법적 고지 및 운영 안내", "IP 수집 및 로그 관리 안내", "광고 및 후원 안내", "브랜드 무관 및 제재 기준 안내", "이용자 보호 및 법령 준수" 항목을 본문 콘텐츠와 Footer 사이에 배치해서, 필요한 정보를 빠르게 확인할 수 있도록 했어요.



⑪ Footer 아래, 작은 신뢰의 장치



Footer 맨 아래에는 현재 상정인사이드의 버전, 마지막 업데이트 시간, 그리고 릴리즈 노트로 바로 이동할 수 있는 하이퍼링크를 넣어 뒀어요.



⑫ 검색 규칙을 붙이면 더 똑똑해지는 검색창



사용자들이 게시물을 검색하기 위해 가장 많이 방문하는 메인 루트에 검색 입력창을 배치했어요. 그냥 키워드만 입력해도 검색이 되지만, creator, title, detail, time 같은 접두어를 검색어 앞에 붙이면 해당 조건에 해당하는 게시물을 우선으로 찾아주도록 검색 규칙을 만들어 뒀어요.




2. 내 활동 페이지와 검색 결과 페이지


① 표준을 참고한 페이지네이션



서버와 클라이언트 양쪽의 연산 부담을 줄이기 위해 KRDS(정부 디자인 시스템) 를 참고해서 표준화된 형태의 페이지네이션을 구현했어요.



② 맥락이 살아있는 댓글 보기



내 활동 페이지에서는 제가 작성한 댓글만 뚝 떼어서 보여주지 않아요. 대신 그 게시물의 전체적인 흐름을 파악할 수 있도록, 제가 단 첫 댓글보다 앞에 있던 댓글부터 마지막 댓글 바로 아래에 달린 댓글까지의 범위를 함께 보여주고, 그중에서 제가 작성한 댓글만 볼드 처리해서 한눈에 구분되도록 디자인했어요.



③ 한 번 더 클릭하면 이어지는 이야기
내 활동 페이지에서 제가 작성한 게시물 옆에는 '게시물 내용 전체보기' 버튼을 넣어서, 클릭 한 번으로 해당 게시물의 전체 내용을 미리보기 페이지에서 바로 확인할 수 있게 했어요. 댓글 옆에도 '이 게시물 작성자의 다른 글 보러가기' 버튼을 넣어서, 내가 댓글을 남긴 게시물의 작성자가 같은 ID로 남긴 다른 글까지 이어서 살펴볼 수 있도록 설계했어요.



④ 화면을 넘겨받아도 안심할 수 있게



내 활동 페이지에는 외부 IP의 ISP /24 대역 정보까지 함께 표시되는데, 이 화면이 그대로 유출되면 위험할 수 있다는 생각이 들었어요. 그래서 '개인정보 화면 보호기'를 만들어서, 필요할 때 IP 정보를 손쉽게 가릴 수 있도록 했어요.




마지막으로 소소한 디테일 하나를 덧붙이자면, https://test.commu.world/ 처럼 실제로는 존재하지 않는 하위 도메인으로 접근하더라도 그냥 에러 화면을 띄우는 대신, 전용 안내 페이지로 자연스럽게 연결되도록 만들어 뒀어요.


BY-NC-ND 라이선스

이 글에는 BY-NC-ND 라이선스가 적용되어 있습니다.


더 많은 프로젝트와 개발 이야기가 궁금하다면
윤주원 개발자의 포트폴리오에서
진행했던 프로젝트와 작업들을 더 자세히 확인하실 수 있습니다.
포트폴리오 보러가기