shwldshwld22 days ago

フレンド限定コンテンツを「存在だけ見せる」マスク実装の設計

GraphQL APIにおいて、完全に非公開にするのではなく、メタデータ(ID、タイトル、公開ステータス等)のみを公開リストに流し、本文などの機密情報をマスクする設計パターン。

背景

ユーザーがアウトプットを精力的に行っていることを非ログインユーザーにも示しつつ、詳細を読むためには会員登録(およびフレンド申請)が必要であることを提示し、サービスへの動機付け(リード獲得)を強化したい。

実装のポイント

  1. 認可レベルの分離:
    • Query.notes のフィルター条件で、publishStatuspublished(公開)および friendOnly(フレンド限定)の両方を取得対象に含める。
  2. フィールドレベルのマスク:
    • 閲覧権限がない場合、content(本文)フィールドなどを null で返す。
    • これにより、フロントエンド側は「記事が存在すること」を検知しつつ、内容の表示を制限できる。
  3. UIによるロック表示:
    • フロントエンド側で note.content == null を判定し、ロックアイコンや "Friend only", "Sign in to read" といったメッセージを表示する。
    • 完全に隠す場合に比べて、ユーザーの活動量を視覚的に示すことができる。

セキュリティ上の考慮事項

  • 安全なデフォルト: 特定のステータス以外を「除外」するよりも、「公開(published)以外はすべて null に倒す」というホワイトリスト形式の実装が安全である。
  • メタデータの露出制限: タイトルや抜粋も伏せる必要がある場合は、それらもマスク対象に含める。

結論

「全か無か(公開か非公開か)」ではなく、メタデータのみを露出させる「段階的公開」を GraphQL のフィールドレベル認可で実現することで、プライバシーの保護とユーザー獲得施策を両立できる。