web-dev-qa-db-ja.com

特定の場合にのみ、Djangoのcsrf保護を無効にするにはどうすればよいですか?

APIのURLがユーザー向けのURLと同じであるDjangoにサイトを作成しようとしています。しかし、POSTリクエストとCSRF保護を使用するページで問題が発生しています。たとえば、ページ/ foo/addがある場合、2つの方法でPOSTリクエストを送信できるようにしたいとします。

  1. フォームを送信するエンドユーザー(セッションCookieを使用して認証される)として。これにはCSRF保護が必要です。
  2. APIクライアントとして(HTTPリクエストヘッダーを使用して認証)。 CSRF保護が有効になっている場合、これは失敗します。

@csrf_exemptなど、CSRFを無効にするさまざまな方法を見つけましたが、これらはすべてビュー全体で無効にします。よりきめの細かいレベルで有効/無効にする方法はありますか?それとも、独自のCSRF保護を最初から実装する必要があるのでしょうか。

32
lucas

DjangoのCSRF保護ドキュメントのタイトルのセクション ビューには1つのパスの保護が必要です があり、解決策を説明しています。ビュー全体で@csrf_exemptを使用するという考え方ですが、APIクライアントヘッダーが存在しないか無効な場合は、@csrf_protectで注釈が付けられた関数を呼び出します。

27
Daniel Trebbien

変更_urls.py_

ルートを_urls.py_で管理している場合、目的のルートを csrf_exempt() でラップできます。 =それらをCSRF検証ミドルウェアから除外します。

たとえば、

_from Django.views.decorators.csrf import csrf_exempt
urlpatterns = patterns(
    # ...
    # Will exclude `/api/v1/test` from CSRF 
    url(r'^api/v1/test', csrf_exempt(TestApiHandler.as_view()))
    # ...
)
_

あるいは、デコレータとして

一部のユーザーは、_@csrf_exempt_デコレータの使用が彼らのニーズにより適していると感じるかもしれません

たとえば、

_from Django.views.decorators.csrf import csrf_exempt
from Django.http import HttpResponse

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')
_
51
Jossef Harush

クラスベースビュー(CBV)を使用していて、csrf_exemptデコレーターを使用する場合は、メソッドデコレーターを使用する必要があります。

from Django.utils.decorators import method_decorator
from Django.views import View
from Django.views.decorators.csrf import csrf_exempt

@method_decorator(csrf_exempt, name='dispatch')
class MyView(View):
    def post(self, request):
        pass  # my view code here
0
Thomas Turner