1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

認証によるファイルダウンロード方式を考察

1
Last updated at Posted at 2025-12-12

はじめまして、グッドパッチでサーバーサイドエンジニアをやってる荒木です。

この記事は Goodpatch Advent Calendar 2025 の 12日目の記事になります。

はじめに

Webサービスで「ユーザーごとに安全にファイルをダウンロードさせたい」「リンクが流出してもアクセスされないようにしたい」という要件は非常に多いです。
この記事では、認証付きファイルダウンロードを実現するための代表的な方式を整理し、それぞれのメリット・デメリットを考えてみます


認証付きファイルダウンロード方式の代表パターン

パターン1:セッションCookie方式 / Bearer Token方式

[ブラウザ] ---(Cookie付きリクエスト)---> [サーバー] ---> [ファイル返却]

メリット

  • 実装が非常にシンプル
  • 既存の認証基盤をそのまま利用可能

デメリット

  • サーバー負荷が高い:すべてのダウンロードがアプリケーションサーバーを経由
  • CDN との相性が悪い:認証が必要なためキャッシュできない
    (※今回は前提としてユーザー毎なので問題無し)

向いている用途

  • 小型〜中型ファイル
  • ダウンロード頻度が低いシステム

パターン2:署名付きURL方式

[サーバー](認証済ユーザーにURL発行)→ [ブラウザ] → [S3などのストレージに直接アクセス]

メリット

  • Webアプリの負荷が軽い
  • 高スケーラビリティ:ダウンロード自体はストレージサービスが処理
  • URLの有効期限・IP制限などができる

デメリット

  • URLが漏えいしたら有効期限内はアクセスされる
  • ダウンロード前にユーザーの認証情報を再確認できない
  • クラウドサービス依存

向いている用途

  • 大規模サービス
  • 大容量ファイルのダウンロード
  • 高スループットが必要なシステム

パターン3:ワンタイムトークン付きダウンロードリンク

① [ブラウザ] → [サーバー](トークン発行)
② [ブラウザ] → ダウンロードURL?token=xxxx
③ [サーバー] → 公開前に token を検証 → ファイル返却

メリット

  • URL流出リスクが低い(即時無効化可能)
  • 厳密なアクセス制御:1回使ったら無効になる
  • ダウンロード通知・ログ取りがやりやすい

デメリット

  • トークン管理テーブルの肥大化(定期的なクリーンアップが必要)
  • サーバー経由でのダウンロードになるため、大容量ファイルは負荷が大きい

向いている用途

  • 機密性の高いファイル
  • ダウンロードをイベントとして扱いたい場合(有料ダウンロードなど)
  • 監査要件があるシステム

パターン4:プロキシ方式

[クライアント] ---> [サーバー](nginx) --(auth_request)--> [認証API]
                       |
                       +---(認証OK)---> [ファイルストレージ/S3]ブラウザ/クライアント 

メリット

  • アプリケーションコードがシンプル
  • nginx が効率的にファイル転送を処理

デメリット

  • インフラ設定が複雑になる
  • nginx の設定スキルが必要

向いている用途

  • 既に nginx を使用しているシステム
  • 内部ストレージからの配信

方式別比較表

方式 セキュリティ 実装難易度 スケーラビリティ
セッションCookie方式
署名付きURL方式
ワンタイムトークン方式
プロキシ方式

補足

  • URL流出のリスクが許容できるかどうかが重視してます

どの方式を選ぶべきか?

  • 大容量ファイルに大量アクセス → 署名付きURL

  • セキュリティ最優先したい → ワンタイムトークン

  • アプリで細かい制御をしたい → セッションCookie方式

  • インフラチームが揃ってます! → プロキシ方式


実際のプロダクトに導入を検討するとしたら?

1. 認証方式の選択

既存サービスでは認証に JWT(JSON Web Token)を採用しており、サーバー側でセッション状態を保持する必要がない。そのため、従来の セッション Cookie 方式 ではなく Bearer Token 方式 を利用することは技術的に適合する。

しかし、Bearer Token を利用して認証付きダウンロードを行う場合、フロントエンド側では以下の対応が必要になる。

  • リクエストに Authorization ヘッダを付与する
  • ブラウザでダウンロードを行うためにBlobを生成し、疑似的にダウンロードをトリガーする必要がある

これは実装が複雑化しやすいため、よりシンプルにリンク操作のみでダウンロードを完結できる ワンタイムトークン方式 を採用することにする。

採用理由まとめ
方式 利点 課題 結論
Cookie セッション方式 ブラウザの通常ダウンロードが簡単 サーバーセッション管理が必要。JWTベースの現構成と非整合 不採用
Bearer Token 方式 現行JWTと整合性が高い フロントで Blob 対応必須で実装が複雑 不採用
ワンタイムトークン方式 署名付きURLのようにリンクだけで完結。実装シンプル サーバー側でワンタイムトークン管理が必要 採用

2. アーキテクチャ / インフラ構成の検討

ワンタイムトークン方式では、ダウンロードごとにワンタイムトークンの発行および検証が必要となるため、既存サービスに負荷が集中する可能性がある。

そのため、影響範囲を限定する目的で 既存サービスとは独立した(疎結合な)環境 を構築する方向で考える。

独立サービスを採用する理由
  • ワンタイムトークン発行APIは頻繁にアクセスされるため、負荷分散しやすい構成を取りたい
  • ダウンロード対象が大きい場合、I/O の負荷が本体サービスに波及するのを避けたい
  • 将来的にダウンロード専用スケール戦略を取れるようにしたい

3. サービス間通信方式の選定

独立環境を構築する場合、既存サービスと新ダウンロードサービス間の通信方式を選定する必要がある。

候補は以下の 3 種:

方式 特徴 評価
gRPC 高速・型安全 新規導入コストが高い。双方向通信までは不要
SQS 非同期処理に向く 即レスが必要な場合に同期APIが必要
REST 現行サービスと同じ方式。導入コストが小さい 今回の要件に十分

今回の要件は「ワンタイムトークンを同期的に発行するだけ」であり、メッセージング基盤やバイナリRPCのメリットがさほど大きくない。

導入コスト・接続性・現構成との整合性から REST を選択


最終的な構成方針(まとめ)

  1. 認証方式はワンタイムトークン方式を採用

    • JWT セッションレス環境と整合性が良い
    • フロント実装が最もシンプル
  2. 既存サービスとは独立したダウンロード環境を構築

    • 負荷分散しやすく、障害や負荷が本体に波及しにくい
    • 将来のスケール戦略にも柔軟
  3. サービス間通信は REST を採用

    • 導入コストと保守性のバランスが最適
    • 現サービスとスムーズに統合できる

おわりに

要件に応じて適切な方式を選択し、セキュリティ対策も忘れずに実装しましょう!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?