6 ポイント 投稿者 GN⁺ 2025-08-16 | 1件のコメント | WhatsAppで共有
  • PureGym アプリの動作の遅さと複雑な入館手順の不便さを解消するため、個人的に Apple Wallet 向けへ最適化した
  • 既存の QRコード は毎回アプリを開いて情報を読み込む必要があり、約47秒かかる非効率な入館方式だった
  • さまざまな リバースエンジニアリング、mitmproxy の使用、PassKit フレームワークなどの技術的プロセスを通じて、自動更新可能な Wallet パス を実装した
  • この過程で PIN コードのセキュリティ上の弱点、API 認証構造、店舗の位置情報など、Web 上で見えてくる 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 でエンコードされた Basic 認証情報もセキュリティは低かった
  • アプリのトラフィックを分析するため、mitmproxy などのプロキシツールでリクエストを傍受した
    • QR コードの JSON 構造は part1(固定 id)、part2(タイムスタンプ)、part3(更新用 salt)で構成されていた
    • API は更新タイミングや失効条件まで案内していた

PassKit: Apple Wallet の可能性

  • Apple Wallet パスは静的なカードではなく、自動更新・プッシュ通知・位置反応などが可能なミニアプリのような仕組みだ
  • PassKit の実装には JSON 仕様、画像リソース、証明書署名、リアルタイム更新用 Web サービスなどが必要だ
  • Apple のデベロッパーポータルで Pass Type ID と WWDR 証明書の発行が必要になる
  • 証明書の署名と管理は煩雑だが、成功すれば実機で滑らかな体験が実現できる

Swift バックエンド構築

  • 一般的には Node.js を使うが、筆者は Swift ベースの Vapor で PassKit Web サービスを自作した
    • パスの更新が必要になると、サイレントプッシュで自動更新を提供する
    • ユーザーが意識しない自然なパス更新を実現した

全国の PureGym 拠点を自動化

  • Apple Wallet パスは指定した場所で自動表示できる
  • PureGym の公式サイトには詳細な座標がないが、API から全国店舗の座標リストを取得できた
  • すべての店舗座標をパースし、各パスに最寄りの店舗を設定した
  • 欠点として、ショッピングセンター内の PureGym では、ただ買い物に行くだけでもパスが表示されるという小さな不便がある

Apple Watch 連携

  • Apple Wallet パスは追加の作業なしで Apple Watch に自動同期される
  • 手首でダブルクリックしてスキャンし、入館まで 3秒 へと大幅に短縮された
  • 93%以上の時間短縮を実現した

数字で見る変化

  • 従来の PureGym アプリでの入館時間: 47秒
  • Apple Wallet パスでの入館時間: 3秒
  • 1週間あたりの平均削減時間: 4.4分(年間3.8時間)
  • 周囲の会員から「こんなアプリあるの?」と23回聞かれ、そのたびに非公式だと説明した
  • 要望はあるが、著作権やサービス規約の都合上、配布する予定はない

おまけ: Home Assistant 連携

  • PureGym API の 館内人数 エンドポイントを通じて、IoT ダッシュボードに現在のジム混雑度を表示した
  • データに基づいて空いている時間に再訪する判断ができ、トレーニング効率やモチベーション向上にもつながった

エンジニアリングの現実と倫理

  • もともとは純粋に個人的な不便を解消するためだったが、PureGym 内部では何年も改善されてこなかった領域だった
  • 組織の外で作られたプロトタイプが、ときに公式ロードマップより早く問題を解決する
  • ただしこれは公式には利用規約違反となる可能性があり、PureGym がいつでも遮断できる
  • 自動化や共有は一切行わず、あくまで個人実験用途に限り、安定性のためキャッシュなどの原則も守った

次のステップと締めくくり

  • 今後は「羞恥心プッシュ通知」のような拡張アイデアも提案できる
  • 実質的な効用は小さくても、年間3.8時間の「不要な操作」を最適化できたことに満足している
  • PureGym が公式実装すれば、より多くの利用者の利便性を高められる
  • 「非公式だが効果的な体験」を生み出した事例として記録された

1件のコメント

 
GN⁺ 2025-08-16
Hacker Newsのコメント
  • 本当に面白くて刺激的な文章だと思う。エンジニアの本質をよく捉えていて、OPが本物のハッカーだと伝わってくる。
    アメリカに3か月滞在していたときにPureGymに加入してPINを受け取り、その後メンバーシップを解約した。ところが後でChromeからPureGymのPINが漏えいしたと通知された。
    2年後に再びアメリカへ行って同じPINを受け取ったが、これはセキュリティ上かなり大きな問題だと思う。
    PureGymアプリとトークンも興味深かったが、ハイドロマッサージチェアの有効化システムにもセキュリティ欠陥を見つけた。どんなPINでも受け付ける構造だった。
    • ChromeがPureGymのPIN漏えいを通知したのは、おそらく誤検知だと思われる。ChromeがHaveIBeenPwned APIを使う際にはこうしたことが起こりうる。
      たとえば87623103のようなPINはハッシュ値558B4C37F6E3FF9A5E1115C66CEF0703E3F2ADEEに変換され、HaveIBeenPwnedのハッシュ範囲で検索すると、実際に複数回漏えいした記録がある。
  • 一度立ち止まって考えるべき話だ。屋外に設置された物理キーパッドは、イギリスの天気とプロテインシェイクと後悔にまみれ、どこかの家のRingドアベルでTikTokライブ配信までされかねない環境にある。それなのに昔のPINを何の問題もなく受け付ける。一方でデジタルQRコードには、NSAも感心するような暗号ローテーションが必要だという。
  • こういう話を読むのは本当に楽しい。アプリがちゃんと動くのを待つ代わりに、自分はPINを直接覚えている。だからOPの提案した方法よりもさらに速く入れるし、機器や別サービスも不要なのでむしろ簡単だと思う。
  • 「Apple Walletを実装しないのにも理由がある」という話を見たとき、PureGymアプリのスクリーンショットを見る限り、実質的にはモバイルWebサイトを薄くラップしただけか、Flutterのような技術を使っているように見える。Apple APIの細かな癖まで扱える社内開発者がいる可能性はかなり低そうだ。
    • これが核心だ。PureGymの本業は、サービス加入者をできるだけ多く集めて退会を難しくすることであって、開発ではない。運がよければ社内のWeb開発者がサイトとデータベースをどうにか維持していて、「アプリっぽく動くようにしてくれ」と外注している程度だろう。運が悪ければWeb関連の業務をすべて外部委託していて、タイトルの一文字を変えるだけでも追加費用がかかるような状況かもしれない。
    • それでも、なぜ学べないのだろうという疑問はある。Google、Stack Overflow、LLMのような道具がこれだけあるのに、いまだに改善がない。おそらくUXを気にする人がそもそも存在しないか、バックエンド開発チームはとっくに去っていて、残っているのは最小人数の低コストなエンジニアで保守しているだけなのだと思う。
    • もしApple Walletを追加するならAndroid Wallet対応も必要になるので、管理すべきコードは増える。それでも少なくとも、アプリを開いた瞬間に常にQRコードを表示するようにはできるはずだ。
    • 自分のスマホにもPureGymアプリがあるが、実際ただPureGymのWebサイトを包んだだけのアプリという感じだ。
  • まさに金言だ。8桁のジムのドア用PINがそのままAPIパスワードであり、大半のユーザーはそれを自分で設定していない。失敗試行に対するレートリミットがあることを願うばかりだ。メールアドレスさえ分かれば即座にAPIへアクセスできる構造に見える。さらに、要求できる権限範囲がきちんと制限されているのかも気になる。
    • OPです。
      APIにすぐアクセス可能かという質問に対しては、その通り。実際にアプリとサイトを使う中でレートリミットに引っかかったことはなく、失敗試行にもかなり寛容だ。
      投稿で紹介したscopeは、公式アプリとGitHub上の非公式クライアントが使っているものと同じだ。
      追加のscopeがある可能性はかなり低い。PureGym PHP WrapperPureGym Attendance Pythonも参考になる。
  • PureGymのアプリロードマップをめぐる議論は、IT業界で本当によくある。
    「その機能を作ると、私たちが自分で責任を負うことになる」みたいな話だ。
    「その通り。じゃあ2028年のロードマップに入れておこう」という冗談もよくある。
    • うちの部署の会議もまったく同じだ。ロードマップや計画の話になると、「これは売上に貢献するのか、ただ金がかかるだけではないか」が核心になる。
      元々やるべきことやウィッシュリストも長いので、機能追加はなかなか進まない。
      PureGymが今いちばんうまくできることは、このアプリを作った開発者に数千ポンドと生涯無料利用権を渡すことだと思う。
  • Apple Developer Portalで発行されるPass Type ID証明書の費用が気になる。
    Apple Walletパスを作りたいが、開発者アカウントの設定や追加費用が負担に感じる。
    • 自分の知る限り、基本の開発者サブスクリプションに含まれている。ただし維持するには毎年開発者サブスクリプションを更新し続ける必要がある。
  • 毎分新しいコードを受け取るようなプッシュ通知が来るなら、バッテリーの問題にならないのだろうかと気になる。
    • 本文を見る限り、コード更新は週1回なので最大でも週1回だと思われる。
    • プッシュ通知にはバックグラウンドモードというものがあり、スマホ側の準備ができたときだけ処理される。
      バッテリー不足時や省電力モードではそもそも配信されず、バッテリー消費を最小化するための仕組みになっている。
      より重要な通知はUI要素が必ず表示され、省電力状態に関係なく届く。
  • 面白くて技術的なディテールが満載の記事で、楽しく読めた。