プレイヤーIDの設計:個人情報を持たない方法
遊びをつくる執筆にClaudeを使用しています。

ブラウザゲームにプレイヤーIDを導入しようとすると、最初の壁として「何を識別子にするか」という問いが出てきます。メールアドレスやユーザー名を自前で管理する方法が思い浮かびますが、それは個人情報の取得・保管・漏洩対策という重い責任をあわせて引き受けることを意味します。 個人情報を持たないIDの設計とは、「誰なのか」ではなく「このブラウザ・このセッションは誰として扱うか」という問いに絞ることです。プレイヤーを特定できる情報なしに、スコアの保存やランキングへの参加を実現できます。この記事では、その設計上の考え方と具体的な実装パターンを整理します。 なお、個人情報保護法や利用規約の法的な細部は国・時期によって変わるため、正式な判断は公式情報や専門家に確認することを前提として、ここでは設計上の考え方を扱います。
「識別」と「認証」を分けて考える
IDの設計でよく混同されるのが、識別(誰かを区別すること)と認証(その人が本人であることを確かめること)の違いです。
スコアを保存したいだけであれば、認証は必ずしも必要ありません。「このプレイヤーのスコアを上書きするとき、前回と同じ人物かどうかを確認する」のが認証であり、ゲームによってはランキングに載せるだけならその厳密さが不要な場合もあります。個人情報を持たない設計を選ぶ場合、まず「自分のゲームは識別だけで済むのか、それとも認証まで必要か」を判断することが出発点になります。
認証なしで識別だけを行う典型例が、ランダム生成IDのローカル保存です。認証ありで個人情報を使わない例が、外部のOAuth(Google・GitHubなどのログインを借りる仕組み)を経由してトークンだけを受け取る方法です。
個人情報を持たないIDの主なパターン
ランダム生成IDをブラウザに保存する
もっとも手軽な方法は、初回アクセス時にUUID(重複しない長い文字列)を生成し、localStorageに保存することです。サーバー側はそのIDしか持たず、メールアドレスや氏名は一切関与しません。
初回: crypto.randomUUID() → localStorage["player_id"] に保存
2回目以降: localStorage["player_id"] を読み出して送信サーバーはこの文字列をキーにしてスコアを保存します。誰のスコアかは分かりませんが、「このIDのスコア」として管理できます。実装が単純で、個人情報を一切取得しない点が最大の利点です。
ただし、ブラウザのデータをクリアするとIDが消え、スコアも引き継げなくなります。別のブラウザや端末では新しいIDになるため、ランキングに同じ人が別人として登場することもあります。「誰でも気軽に遊べる」ゲームには十分機能しますが、本格的な進捗管理には向きません。
外部OAuthのトークンだけを受け取る
GoogleやGitHubなどのOAuthを経由すると、プレイヤーは既存のアカウントでログインでき、作者側はその外部サービスが発行するユーザーIDのみを受け取れます。メールアドレスを取得する権限(スコープ)を要求しなければ、手元には「Googleが発行した不透明な文字列」だけが残ります。
この文字列はGoogleアカウントと1対1で対応しているため、ブラウザをまたいだ識別が可能です。プレイヤーは同じGoogleアカウントでどのデバイスからログインしてもスコアが引き継がれます。作者側がメールアドレスを持たなければ、メールアドレスの管理責任は生じません。
注意点として、OAuthの設定でどのスコープを要求するかは慎重に選ぶ必要があります。メールアドレスや氏名を要求するスコープを追加した瞬間に個人情報を取得することになるため、必要な権限だけに絞る設計が重要です。
アソバースのSDKを経由する方法
アソバースでは、作者がSDKを組み込んだゲームに限り、プラットフォームの共通ログインとクラウドセーブを利用できます。この場合、プレイヤーIDの管理はプラットフォーム側が担うため、作者が独自にIDを設計・保管する必要がなくなります。個人情報の扱いに不安がある場合、この仕組みに乗ることで識別と保存の責任をプラットフォームに委ねられます。
ID設計で失敗しやすい点
スコープの取りすぎ。 OAuthを使うとき、ライブラリのサンプルコードがメールアドレスを含むスコープを既定で含んでいることがあります。コピー&ペーストで動かしてから「実は個人情報を取っていた」と気づくケースです。認証後にサーバーへ何が渡ってくるかをログで確認する習慣をつけてください。
IDの衝突を甘く見る。 UUIDは衝突の確率が極めて低いですが、ゼロではありません。また、悪意あるプレイヤーが他者のIDを推測・なりすましするリスクもあります。ランキング改ざんを防ぎたいなら、IDをトークンとして署名する(JWTなど)方向を検討してください。
削除手段を作らない。 個人情報を持たないIDであっても、プレイヤーのデータをサーバーに蓄積するなら、削除の手段を用意することが一般的な設計上の配慮です。ゲーム内に「データを消す」ボタンを置くか、問い合わせで対応できる体制を整えておくことを推奨します。
localStorageの揮発性を説明しない。 ランダム生成IDをlocalStorageで管理する場合、プレイヤーが気づかずにブラウザデータを消してIDを失うことがあります。ゲーム内に「このIDを控えておくと引き継ぎに使えます」という案内を置くか、そもそも揮発を前提とした設計(スコアが消えても再プレイすれば戻る)にするか、どちらかを意識的に選んでください。
設計を選ぶ判断基準
どのパターンを選ぶかは、ゲームの性質によります。
- 一回遊べればいいカジュアルゲーム、適したパターン:localStorage + UUID(認証不要)
- スコアを端末をまたいで持ち運びたい、適したパターン:OAuthトークン(メール不要スコープ)
- セーブ管理をプラットフォームに任せたい、適したパターン:アソバースSDKの共通ログイン
- ランキング改ざんを防ぎたい、適したパターン:署名付きトークン(JWTなど)
「なるべく手を動かしたくない」「個人情報の扱いに自信がない」という場合は、最初にlocalStorage + UUIDで動くものを作り、必要になってからOAuthやSDKへ移行するのが現実的な順序です。
次の行動
まずゲームの仕様を見直し、「識別だけで足りるか、認証が必要か」を一行で書き出してください。識別で足りるならcrypto.randomUUID()とlocalStorageの組み合わせを試し、端末をまたいだ引き継ぎが必要になった段階でOAuthやアソバースSDKへの移行を検討する順で進めると、最初から複雑な仕組みを抱えずに済みます。OAuthのスコープ設定や個人情報保護法の適用については、公式ドキュメントと必要に応じて専門家の確認をあわせて行ってください。
参考資料
- MDN Web Docs「Web Crypto API」
- MDN Web Docs「Web Storage API(localStorage)」
- OAuth 2.0 仕様(RFC 6749)
- OpenID Connect Core 1.0 仕様
- 個人情報保護委員会「個人情報の保護に関する法律についてのガイドライン」

