21

ユーザーの写真が非公開のアプリがあります。写真(サムネイルも)をAWS s3に保存します。サイトには、ユーザーが自分の写真 (サムネイルなど) を表示できるページがあります。今私の問題は、これらのファイルをどのように提供するかです。私が評価したいくつかのオプションは次のとおりです。

  • 署名付き URL 生成を使用して CloudFront (または AWS) からファイルを提供します。しかし問題は、ユーザーがページを更新するたびに、非常に多くの署名済み URL を再度作成してロードする必要があることです。したがって、ブラウザに画像をキャッシュすることはできません。これは良い選択でした。とにかくまだjavascriptでやるべきことはありますか? セキュリティ上の問題により、これらの URL の有効性を長く維持することはできません。次に、その時間枠内で誰かがその URL を入手した場合、アプリからの認証を実行せずにファイルを表示できます。
  • その他のオプションは、S3 サーバーからストリーミングした後、Express アプリ自体からファイルを提供することです。これにより、http キャッシュ ヘッダーを使用できるため、ブラウザーのキャッシュが有効になります。また、認証されていないと誰もファイルを表示できないようにします。理想的には、ファイルをストリーミングしたいと思います。NGINX プロキシ リレーを使用してホストしているファイルを、反対側の NGINX にストリーミングします。しかし、私が見るように、それはファイルが同じシステムのファイルに存在する場合にのみ可能です。しかし、ここではそれをストリーミングして、ストリームが完了したら戻る必要があります。ファイルをローカルに保存したくない。

2つのオプションのどちらがより良い選択であるかを評価することはできません?? できるだけ多くの作業を S3 またはクラウドフロントにリダイレクトしたいのですが、署名された URL を使用しても、リクエストは最初にサーバーに送信されます。キャッシング機能も欲しい。

では、どのような方法が理想的でしょうか?それらの方法に関する特定の質問に対する答えはありますか?

4

4 に答える 4

22

S3からストリーミングするだけです。これは非常に簡単ですが、署名付き URL ははるかに困難です。画像を S3 にアップロードするときは、ヘッダーcontent-typeとヘッダーを必ず設定してください。content-length

var aws = require('knox').createClient({
  key: '',
  secret: '',
  bucket: ''
})

app.get('/image/:id', function (req, res, next) {
  if (!req.user.is.authenticated) {
    var err = new Error()
    err.status = 403
    next(err)
    return
  }

  aws.get('/image/' + req.params.id)
  .on('error', next)
  .on('response', function (resp) {
    if (resp.statusCode !== 200) {
      var err = new Error()
      err.status = 404
      next(err)
      return
    }

    res.setHeader('Content-Length', resp.headers['content-length'])
    res.setHeader('Content-Type', resp.headers['content-type'])

    // cache-control?
    // etag?
    // last-modified?
    // expires?

    if (req.fresh) {
      res.statusCode = 304
      res.end()
      return
    }

    if (req.method === 'HEAD') {
      res.statusCode = 200
      res.end()
      return
    }

    resp.pipe(res)
  })
})
于 2013-07-14T10:19:25.230 に答える
1

写真を本当に非公開にする必要がある場合は、CloudFront オプションを使用することに関心があります。独自のセキュリティ ポリシーを管理する際の柔軟性が大幅に向上するようです。nginx のセットアップは、必要以上に複雑になる可能性があると思います。Express は、リクエストを使用して S3 からアイテムを取得し、許可されたユーザーにストリーミングするリモート プロキシとして機能する非常に優れたパフォーマンスを提供するはずです。ハッシュ署名を使用してブラウザーでの永続的なキャッシュを有効にする Asset Rack を検討することを強くお勧めします。各ファイルの MD5 を計算する必要があるため (おそらくアップロード時?)、ストリーミング時には実行できないため、デフォルトのラックを使用することはできません。ただし、アプリケーションによっては、ブラウザーが画像を再フェッチする必要がないため、多くの労力を節約できます。

于 2013-07-07T22:59:07.613 に答える
0

2 番目のオプションについては、キャッシュ制御ヘッダーを S3 に直接設定できるはずです。

最初のオプションについて。イメージを別の方法で保護することを検討しましたか? S3 に画像を保存するとき、ハッシュ化され、ランダム化されたファイル名を使用できませんでしたか? ファイル名を推測しにくくするのは非常に簡単です + こうすれば、画像を表示するときにパフォーマンスの問題が発生しません。

これはフェイスブックで使うテクニックです。URL を知っていれば、ログアウトしても画像を表示できます。

于 2013-07-10T23:27:05.400 に答える