$ cd /blog

서버 없이 Flutter 게임에 글로벌 랭킹 만들기 — Vercel + Neon + HMAC 구현기

1인 개발 모바일 게임에 계정 없이 글로벌 랭킹을 붙인 실전 기록. Vercel API Route와 Neon 서버리스 DB, HMAC 서명으로 점수 위조까지 막은 설계를 정리했습니다.


안녕하세요. Jay입니다!

모바일 게임을 만들다 보면 반드시 한 번은 마주치는 갈림길이 있습니다. "글로벌 랭킹을 넣고 싶은데... 서버를 운영해야 하나?" 1인 개발자에게 서버는 부담입니다. 월 비용도 비용이지만, 게임보다 서버 관리에 시간을 뺏기는 게 더 무섭죠. 저도 최근 출시한 힐링 퍼즐 게임 '알롱이'에 글로벌 랭킹을 붙이면서 같은 고민을 했고, 결론은 "서버를 새로 만들지 않는다"였습니다. 이미 운영 중이던 Next.js 사이트(Vercel)에 API 3개를 얹는 것으로 끝냈거든요. 오늘은 그 구현기를 공유합니다.

🧱 스택: 이미 있는 것들로 조립하기

새로 만든 것은 사실상 없습니다.

  • API: Vercel에 배포된 Next.js의 API Route 3개 — 닉네임 등록, 랭킹 조회, 점수 등록
  • DB: Neon(서버리스 PostgreSQL) — 무료 티어, 안 쓰면 잠들고 요청 오면 깨어남
  • : Flutter 게임에서 HTTP 호출만 추가

덕분에 추가 비용 0원으로 글로벌 랭킹이 생겼습니다. 관리할 서버 인스턴스도, 스케일링 걱정도 없습니다. 캐주얼 게임의 랭킹 트래픽 정도는 서버리스 무료 티어로 충분히 감당됩니다.

🪪 계정 없이 닉네임 소유권 지키기

랭킹의 첫 관문은 "이 점수가 누구 것인가"입니다. 회원가입을 넣으면 해결되지만, 잠들기 전에 가볍게 하는 힐링 게임에 로그인 화면은 어울리지 않죠. 그래서 이렇게 설계했습니다.

  • 최초 실행 시 닉네임 게이트: 앱 첫 진입에 닉네임을 정합니다. 추천 생성기("멋진 참새" 같은 형용사×명사 조합)로 고민 시간을 줄였고, 오프라인이면 '나중에'로 건너뛸 수 있게 했습니다.
  • 디바이스 토큰 = 소유권: 기기에서 만든 랜덤 토큰을 iOS Keychain에 저장하고, 서버는 닉네임과 토큰을 묶어 저장합니다. 계정 없이도 "내 닉네임"이 지켜집니다.
  • 중복 방지: DB에서 소문자 기준 UNIQUE 제약 + 금칙어 필터로 처리했습니다.

🔏 점수 위조는 HMAC 서명으로 막기

랭킹 API를 열어두면 누군가는 반드시 가짜 점수를 쏩니다. 그래서 점수 등록 요청에 HMAC 서명을 요구했습니다.

  • 앱이 디바이스토큰:점수:단계:타임스탬프를 비밀키로 서명해서 보내면, 서버가 같은 방식으로 검증합니다. 서명이 다르면 401.
  • 타임스탬프 신선도 검사로 캡처해둔 요청의 재사용(리플레이)을 막고,
  • 점수 상한선IP당 분당 3회 rate limit으로 비정상 값과 도배를 걸러냅니다.

솔직히 말하면 완벽하진 않습니다. 앱 안에 키가 있는 이상 마음먹은 공격자는 뚫을 수 있어요. 하지만 캐주얼 게임 랭킹에 필요한 건 은행 수준 보안이 아니라 "쉽게 장난칠 수 없는 정도의 턱"이고, 이상값이 올라오면 서버에서 SQL 한 줄로 정리하면 됩니다.

🥇 랭킹 설계: 한 명이 TOP 50을 독식하지 않게

처음 구현은 단순히 점수순 정렬이었는데, 바로 문제가 보였습니다. 잘하는 한 명이 여러 판의 기록으로 순위표를 도배하는 거죠. 그래서 저장은 판마다 하되, 조회할 때 플레이어당 최고점 1개만 뽑도록 했습니다(PostgreSQL의 DISTINCT ON이 딱입니다). 여기에 50위 밖 유저를 위한 내 순위 쿼리(나보다 높은 최고점 수 + 1)와 월간/전체 필터를 더했습니다. 앱 쪽에서는 최고 기록을 갱신한 판만 자동 등록하게 해서 서버 요청 자체도 줄였습니다.

💡 Jay의 한마디

이번 구현에서 제일 만족스러운 부분은 게임이 여전히 완전 오프라인이라는 점입니다. 랭킹 등록이 실패하면 조용히 로컬 기록만 남기고 넘어갑니다. 네트워크가 게임을 막는 순간 힐링 게임의 정체성이 깨지니까요. 그리고 한 가지 팁 — 랭킹처럼 닉네임이 노출되는 기능은 애플 심사에서 UGC(사용자 생성 콘텐츠)로 봅니다. 부적절한 닉네임을 신고할 수단개인정보처리방침에 수집 항목(닉네임·점수·기기 식별자) 반영까지 챙겨야 심사를 한 번에 통과할 수 있습니다. 실제로 이 랭킹을 실은 업데이트는 무사히 심사를 통과해 지금 라이브로 돌고 있어요.

결론

서버 없는 1인 개발 게임이라도 글로벌 랭킹은 충분히 만들 수 있습니다. 핵심은 네 가지입니다. ① Vercel + Neon 같은 서버리스 조합으로 비용 0원에 시작하고 ② 디바이스 토큰으로 계정 없이 소유권을 해결하고 ③ HMAC 서명 + rate limit으로 적당한 턱을 세우고 ④ 플레이어당 최고점 dedupe로 순위표를 공정하게 유지하는 것. 여러분의 게임에도 "전 세계 순위"라는 재미를 부담 없이 붙여보세요.

다음에도 유익한 포스팅으로 찾아오겠습니다. 감사합니다!

#Flutter#글로벌 랭킹#Vercel#Neon#서버리스

$ ls related/

더 많은 IT·AI 활용법이 궁금하다면?

매주 새로운 실전 가이드가 업데이트됩니다.

전체 글 보기