3P by GN⁺ 13시간전 | ★ favorite | 댓글 1개
  • 필자는 PureGym 앱의 느린 사용성과 복잡한 입장 과정을 불편하게 여기고, 이를 Apple Wallet으로 최적화함
  • 기존 QR 코드는 매번 앱을 열고 정보를 불러와야 하며, 약 47초가 걸리는 비효율적 진입 방식임
  • 다양한 리버스 엔지니어링, mitmproxy 사용, PassKit 프레임워크 등 기술적 과정을 통해 자동 갱신 가능한 Wallet 패스를 구현함
  • 이 과정에서 PIN 코드의 보안 허점, API 인증 구조, 지점 위치 정보 등 웹상에서 드러난 PureGym의 내부 동작을 확인함
  • 최종적으로 3초 만에 입장하는 사용자 경험을 만들어냈으며, 개인적인 실험으로 끝내고 공식 서비스가 아님을 명확히 함

47초: 불편함의 시작

  • 평일 오전 11:15, PureGym 입구에서 앱을 여는 데 47초가 소요됨
  • 신호가 약하고, Wi-Fi 접속과 앱 실행, 각종 푸쉬 알림, 특별 할인 제안 등을 넘겨야 QR 코드가 나타남
  • 실제 QR 코드가 뜨기까지 오래 걸리고, 다른 회원의 눈치를 보게 됨
  • 주 6회 반복 시 매주 282초가 소모되는 비효율적 경험임
  • Amazon Fresh와 같은 무비접 경험과 비교해 PureGym의 진입 UX는 매우 뒤떨어짐

8년 된 PIN의 미스터리

  • 필자는 8자리 PIN 코드를 8년째 동일하게 사용함
  • 이 PIN은 만료되지도 변경되지도 않음
  • 반면 앱 내 QR 코드는 1분마다 새로운 값으로 교체됨
  • 실질적 보안 수준과 실제 구현 간에 큰 모순이 존재함
  • PIN 방식은 극단적으로 오래 유지되면서 QR 코드만 엄격하게 보호되는 "보안 쇼" 현상임

mitmproxy로 PureGym 이해하기

  • 처음에는 QR 코드 스크린샷을 Apple Wallet에 넣어 사용하려 했으나 즉시 작동하지 않음
  • PureGym의 QR 코드는 동적으로 생성, 대략 1주 만에 만료되지만 앱에서는 1분마다 갱신함
  • GitHub에서 "PureGym" 관련 레포를 검색해 API 인증 구조를 발견함
    • 로그인용 8자리 PIN이 API 패스워드와 동일하게 사용됨
    • Base64로 인코딩된 기본 인증 정보도 보안성이 떨어짐
  • 앱 트래픽을 분석하기 위해 mitmproxy 등 프록시 도구로 요청을 가로챔
    • QR 코드의 JSON 구조는 part1(고정 id), part2(타임스탬프), part3(갱신용 salt)로 이루어짐
    • API에서 갱신 타이밍, 만료 조건까지 모두 안내함

PassKit: Apple Wallet의 잠재력

  • Apple Wallet 패스는 정적 카드가 아닌, 자체 갱신·푸쉬 알림·위치 반응 등이 가능한 미니 앱 구조
  • PassKit 구현에는 JSON 명세, 이미지 리소스, 인증서 서명, 실시간 갱신용 웹서비스 등이 필요함
  • Apple의 개발자 포탈에서 Pass Type ID 및 WWDR 인증서 발급이 요구됨
  • 인증서 서명과 관리가 까다롭지만, 성공하면 실제 기기에서 매끄러운 경험이 가능함

Swift 백엔드 구축

  • 일반적으로 Node.js를 쓰지만, 필자는 Swift 기반 Vapor로 직접 PassKit 웹서비스 구현
    • 패스 갱신 필요시, 사일런트 푸쉬로 자동 업데이트 제공
    • 사용자가 인식하지 못하는 자연스러운 패스 갱신 실현

전국 PureGym 위치 자동화

  • Apple Wallet 패스는 지정 위치에서 자동 노출 가능
  • PureGym 공식 사이트에는 상세 좌표가 없으나, API에서 전국 지점의 좌표 리스트 획득
  • 모든 지점 좌표를 파싱해 패스마다 가까운 지점을 지정함
  • 단점: 쇼핑센터 내 PureGym인 경우, 단순 쇼핑에도 패스가 뜨는 소소한 불편함

Apple Watch 연동

  • Apple Wallet 패스는 별도 작업 없이 Apple Watch에서 자동 동기화됨
  • 손목에서 두 번 클릭 후 스캔, 입장까지 3초 소요로 대폭 단축
  • 93% 이상의 시간 절감 실현

수치로 보는 변화

  • 기존 PureGym 앱 진입 시간: 47초
  • Apple Wallet 패스 진입 시간: 3초
  • 한 주 평균 절감 시간: 4.4분(연 3.8시간)
  • 주변 회원들이 "이런 앱 있냐"고 23회 물어봄, 모두 비공식임을 설명함
  • 요청이 있지만 저작권/서비스 정책상 배포 계획 없음

보너스: Home Assistant 연동

  • PureGym API의 실내 인원수 엔드포인트를 통해 IoT 대시보드에 현재 체육관 혼잡도를 표시함
  • 데이터 기반으로 한산한 시간 재방문 결정 가능, 운동 효율/동기 상승 효과

엔지니어링 현실과 윤리

  • 순수한 개인 불편함 해결이었으나, PureGym 내부에서는 다년간 개선하지 않은 영역임
  • 조직 밖에서 만들어진 프로토타입이 때로는 공식 로드맵보다 빨리 문제를 해결함
  • 이것이 공식적으로는 약관 위반일 수 있고, 언제든 PureGym이 차단 가능함
  • 절대 자동화/공유는 하지 않고 오로지 개인 실험 용도, 안정성을 위해 캐시 등 원칙 준수

다음 단계와 마무리

  • 앞으로 "부끄러움 푸쉬 알림" 등 확장 아이디어 제안이 가능
  • 실질적 효용은 작지만, 연간 3.8시간의 "불필요한 동작"을 최적화함에 만족감 느낌
  • PureGym이 공식 구현을 한다면 더 많은 이용자 편의성 확보 가능함
  • "비공식이지만 효과적인 경험"을 창출한 사례로 기록됨
Hacker News 의견
  • 정말 재미있고 영감을 주는 글이라고 생각함, 엔지니어의 본질을 잘 담아냈음, OP가 진정한 해커임이 드러남<br>미국에 3개월 동안 있을 때 PureGym에 가입해서 PIN을 받았고, 나중에 멤버십을 취소함, 그런데 크롬에서 PureGym PIN이 유출되었다고 알려줌<br>2년 후 다시 미국에 가서 같은 PIN을 받았고, 이는 보안상 굉장한 문제라고 생각함<br>PureGym 앱과 토큰도 흥미로웠는데, 하이드로 마사지 의자 활성화 시스템에서 보안 결함도 발견했음, 어떤 PIN이든 받아들이는 구조였음

    • 크롬이 PureGym PIN 유출을 알린 것은 아마 오탐으로 보임, 크롬이 HaveIBeenPwned API를 사용할 때 이런 일이 발생할 수 있음<br>예를 들어 87623103 같은 PIN은 해시값이 558B4C37F6E3FF9A5E1115C66CEF0703E3F2ADEE로 변환되고<br>HaveIBeenPwned 해시 범위에서 검색하면 실제로 여러 번 유출된 기록이 있음
  • 한 번만 생각해봐야 할 문제임, 야외에 놓인 물리적 키패드는 영국의 날씨, 단백질 셰이크, 후회로 덮여 있고, 어떤 집의 링 도어벨로 틱톡 라이브 중계까지 될 수 있는 곳임<br>그런데도 내 예전 PIN을 문제없이 받아들임, 반면 디지털 QR코드는 NSA가 감탄할 정도의 암호화 회전이 필요함

  • 이런 이야기를 읽는 게 너무 즐거움, 앱이 제대로 작동할 때까지 기다리는 대신 직접 PIN을 외움<br>그래서 OP가 제안한 방법보다도 더 빠르게 들어갈 수 있고, 기기나 별도 서비스도 필요 없어서 더 간편하다고 생각함

  • “Apple Wallet을 구현하지 않는 것도 다 이유가 있다”라는 글을 봤을 때, PureGym 앱의 스크린샷을 참고하면 사실상 모바일 웹 사이트를 얇게 감싼 수준이거나 Flutter 같은 기술을 쓴 것으로 보임<br>애플 API의 미묘한 부분까지 다룰 수 있는 사내 개발자가 있을 확률은 매우 낮아 보임

    • 이게 핵심임, PureGym은 서비스 가입자를 최대한 많이 받고 탈퇴는 어렵게 만드는 게 본업임, 개발이 본업이 아님<br>운이 좋으면 내부 웹 개발자가 사이트와 데이터베이스만 겨우 관리하고, 앱처럼 동작하게 해달라며 외주를 맡김, 운이 나쁘면 모든 웹 업무를 외주업체에 맡기고 제목 한 글자 바꾸려고 해도 추가 비용을 내는 상황임

    • 그런데 왜 배우지 못할까라는 의문이 듦, 구글, Stack Overflow, LLM 같은 도구가 많은데도 여전히 개선이 없음<br>아마도 UX를 신경 쓰는 사람이 아예 없거나, 백엔드 개발팀은 다 떠난지 오래고 남은 건 최소 인원의 저렴한 엔지니어로 유지하고 있기 때문이라고 생각함

    • 만약 Apple Wallet을 추가한다면 Android Wallet 지원도 해야 하므로 관리할 코드가 늘어남<br>그래도 최소한 앱을 켜자마자 QR 코드를 항상 보여주게는 만들 수 있을 것 같음

    • 내 휴대폰에도 PureGym 앱이 있는데, 실제로 그냥 PureGym 웹사이트를 감싼 앱 느낌임

  • 순금 같은 말임, 8자리 짐 도어 PIN이 곧 API 비밀번호이고, 대다수 사용자가 직접 설정하지 않았음<br>실패 시도에 대해 레이트 리미트가 있길 바라는 중임<br>이메일 주소만 알면 곧바로 API 접근이 되는 구조 같음<br>또 요청할 수 있는 권한 범위도 잘 제한되어 있는지 궁금함

    • OP임<br>API 접근이 바로 가능하냐는 질문에는 맞음, 실제로 앱과 사이트를 쓰면서 레이트 리미트에 걸려본 적이 없음, 실패 시도에 꽤 관대함<br>포스트에 소개한 scope는 공식 앱과 GitHub의 비공식 클라이언트들이 쓰는 것과 동일함<br>추가 scope가 있을 확률은 매우 낮음<br>PureGym PHP WrapperPureGym Attendance Python도 참고할 만함
  • PureGym의 앱 로드맵 논의를 IT 업계에서 많이 겪음<br>“이 기능을 만들면 우리가 직접 책임을 져야 한다”라는 식<br>“맞는 말임, 그럼 2028년 로드맵에 넣어두자”라는 농담도 많이 함

    • 내 부서 미팅도 똑같음, 로드맵과 계획 이야기를 할 때 “이게 우리 매출에 도움이 되냐, 돈 드는 일 아니냐”가 핵심임<br>원래 할 일이나 위시리스트도 길어서 기능 추가가 잘 안 됨<br>PureGym이 지금 가장 잘할 수 있는 건, 이 앱 만든 개발자에게 몇 천 파운드와 평생 무료 이용권을 주는 것이라고 생각함
  • Apple Developer Portal에서 발급하는 Pass Type ID 증명서 비용이 궁금함<br>Apple Wallet 패스를 만들고 싶은데 개발자 계정 설정과 추가 비용이 부담스러움

    • 내가 아는 한 기본 개발자 구독에 포함되어 있음, 다만 매년 개발자 구독을 갱신해야 계속 유지할 수 있음
  • 매 분마다 새로운 코드를 받으라고 푸시 알림이 온다면 배터리 문제 아닐지 궁금함

    • 본문을 보면 코드 갱신이 주 1회라 주 1회가 최대일 것으로 예상함

    • 푸시 알림에는 백그라운드 모드라는 게 있어서, 폰이 준비됐을 때만 처리됨<br>배터리 부족 시나 절전 모드에선 아예 전달되지 않아 배터리 소모를 최소화하려고 만들어진 구조임<br>더 중요한 알림은 UI 요소가 반드시 보여야 하고, 절전 상황과 관계없이 도착함

  • 재미있고 기술적인 디테일이 가득한 글이라 즐겁게 읽었음