2

Djangoで画像ファイルを提供するベストプラクティスは何ですか?私は静的な画像で応答したい、私はHerokuに私のDjangoアプリを配備している。Djangoで静的ファイルを提供するためのベストプラクティス

whitenoise.middleware.WhiteNoiseMiddlewareの代わりにdjango.middleware.security.SecurityMiddlewareを使用すると重大な欠点がありますか?

以下のコードは、ホワイトニングを使用するのと比べて効率が悪いですか? settings.MEDIA_ROOTから静的なファイルを提供するのと同じイメージを配信していますか?

img = os.path.join(settings.MEDIA_ROOT, filename) 
try: 
    with open(img, "rb") as f: 
     return HttpResponse(f.read(), content_type="image/jpeg") 
except IOError: 
    failedResponse = '{"detail": "No image found"}' 
    return HttpResponse(failedResponse) 
+0

django middilewareを追加しているときにどのような問題が発生していますか? – Cadmus

+0

whitenoiseのドキュメント[here](http://whitenoise.evans.io/en/stable/django。html)は、ミドルウェアを使うべきではないと言っています。私はちょうどdjango.securityを使ってwhitenoiseを使うことの欠点があるかどうかを知りたがっています。 –

+1

Djangoには何らかの組み込みセキュリティ機構があります。私の提案はDjangoのミドルウェアであるBcozをフォローアップしています。しかし、whitenoiseは第三者のパッケージです 私たちは知識なしでそれらを信頼することはできません。 – Cadmus

答えて

5

コメント:

ここでホワイトノイズのドキュメントは、我々はミドルウェアの両方を使用してはならないと私はちょうどdjango.securityの上にホワイトノイズを使用するという欠点があったかどうかを知りたいと思ったことを言う - マナンメータ30分前

いいえ、ドキュメントのそのセクションはMIDDLEWARE_CLASSESの順番を参照しています。 DjangoのセキュリティミドルウェアでWhitenoiseをうまく使うことができます。

編集しsettings.pyファイルとDjangoのSecurityMiddlewareから離れて他のすべてのミドルウェアの上、MIDDLEWARE_CLASSESリストにホワイトノイズを追加します:

MIDDLEWARE_CLASSES = [ 
    # 'django.middleware.security.SecurityMiddleware', 
    'whitenoise.middleware.WhiteNoiseMiddleware', 
    # ... 
] 

SnakeFczの勧告を以下のドキュメントから

抜粋Djangoを静的に動作させることは良い考えではありません - Whitenoiseパッケージは、Djangoを介して静的に機能する高性能のメソッドとして設計されています。 heroku docsWhitenoise docsを参照してください。あなたの編集へ


返信:ジャンゴで

、静的なアプリが展開されたとき(静的のまま)に変更はありませんあなたは開発中に作成JS/CSS /画像のようなものを指し、 。メディアは、ユーザーがアップロードした画像や動画、または生成された画像(サムネイルなど)などです。

スタティックとメディアを別々にSTATIC_ROOTとMEDIA_ROOTディレクトリに保存することをお勧めします。次に、本番環境では、これらのディレクトリにURL STATIC_URLとMEDIA_URLのWebサーバーを構成します。 Whitenoiseは、Webサーバを設定することなく、これらのフォルダからファイルを正しく提供することで、物事を少し簡素化します。次のように

Djangoが正しくイメージを提供するために取得するための主な懸念

は、(静的またはメディア)は次のとおりです。

  • パフォーマンス - Djangoは資産を提供するために最適化されていないので、それはを通じて提供するよりも遅くなりますNginx/ApacheなどのWebサーバー。イメージリクエストの多くは標準ページリクエストを遅くします。なぜなら、それらはキューに入れられて応答時間が長くなるからです。あなたのウェブサイトが小さくても問題はないかもしれませんが、トラフィックが厄介なときにあなたのウェブサイトの仕組みを変えてください!

  • キャッシュヘッダー - 返されるときにDjangoは画像にキャッシュコントロールヘッダーを追加することを知りませんが、Whitenoiseのようなパッケージは分かりやすいキャッシュヘッダーを追加します(最も重要なのはキャッシュの有効期限です。例えばユーザーのブラウザーの長さあなたのイメージにぶら下がる)。

ホワイトノイズは、Djangoはあなたがイメージを返す方法に依存しない、可能性があることを扱ういくつかの他のヘッダがあります。

  • メディアタイプ - ブラウザが応答彼らに対処する方法を知っておく必要がありますが、だから、Content-Typeというヘッダがあります。上記のコードでは、すべてのファイルをイメージとして返します。ユーザーがPNGを要求するとどうなりますか?

  • コンテンツの長さ - ブラウザはコンテンツの長さ(レスポンスのサイズ)を使用してプログレスバーを表示し、その他の最適化(チャンクでレスポンスを読むなど)を行います。

  • 圧縮 - ほとんどのブラウザとWebサーバー(およびWhitenoise)はgzipなどの圧縮方式をサポートしています。最近ではbrotli(Googleによって構築されています)もサポートしています。 Webサーバーは、転送中に帯域幅を最小限に抑えるために、ファイルを圧縮します(通常は一度、次に圧縮ファイルがキャッシュされます)。イメージとフォーマットによっては、イメージをサイズの約60〜70%まで圧縮することができます。 lenaビットマップ上

    デモ:

    ❯ brew install gzip brotli 
    
    ❯ gzip -k -v lena.bmp 
    lena.bmp:  18.3% -- replaced with lena.bmp.gz 
    
    ❯ bro --input lena.bmp --output lena.bmp.bro 
    
    ❯ ls -lh lena* 
    [email protected] 1 alex staff 768K Feb 16 21:41 lena.bmp 
    -rw------- 1 alex staff 527K Feb 16 21:45 lena.bmp.bro 
    [email protected] 1 alex staff 627K Feb 16 21:41 lena.bmp.gz 
    
  • セキュリティ - Webサーバーに静的な資産を提供残してもう一つの理由は、セキュリティ上の弱点の可能性です!

    あなたのビューで画像を提供するコードは次の通りで、URLはstatic/<filename>に設定されているとします。

    img = os.path.join(settings.MEDIA_ROOT, filename) 
    with open(img, "rb") as f: 
        return HttpResponse(f.read(), content_type="image/jpeg") 
    

    悪意のあるユーザーがyoursite.com/static//Users/alex/.ssh/id_rsaにナビゲートしたとします。その後、ファイル名は/Users/alex/.ssh/id_rsa次のようになります。

    filename = '/Users/alex/.ssh/id_rsa' 
    os.path.join(settings.MEDIA_ROOT, filename) 
    # '/Users/alex/.ssh/id_rsa' 
    

    は、ビューは、Webサーバの秘密鍵を読み込み、悪意のあるユーザーにそれを返します。うわー!今すぐあなたのサーバーにsshすることができます。


Herokuの上のメディア:あなたはHerokuのにデプロイしている場合心に留めする

ことの一つは、彼らのdynos作業方法です。 Heroku dynosは非常に頻繁に(あなたが配備されるたびに、少なくとも毎日)作成され、破壊されるので、ファイルシステムに頼ることはできません。一度に2つ以上のダイノスを実行することもできます。これらはデータセンター内の異なるホスト上で実行される完全に別々のコンテナで、ファイルシステムを共有しません。通常、ユーザーがアップロードしたメディアを扱う場合は、Django-storagesを使用して、ファイルシステムではなくS3(AWSのストレージサービス)にイメージを保存します。データベースにイメージを保存することもできますが、それはうまくスケーリングされません。 S3にメディアを保存するために設定されたDjangoアプリケーションの例については、https://github.com/eknuth/django-heroku-s3-bootstrap-demoを参照してください。

+0

私たちはとにかく右に行うことができます、私はDjangoの組み込みミドルウェアを使用しようとしている、私は彼らがパフォーマンスの問題を持っていない可能性があります – Cadmus

+2

@ SnakeFczいいえ、いずれの方法は "正しい"ではない - Djangoは静的プロダクションとWhitenoise *のファイルは*です。私はあなたが使用しようとしているパッケージを理解せずに初心者のユーザに推奨するべきではないと思います。 –

+0

ほとんどはサードパーティのパッケージを推奨しません – Cadmus

関連する問題