1. ホーム
  2. django

[解決済み] DjangoのRest Frameworkはcsrfを削除します。

2022-04-30 05:54:04

質問

Django Rest Frameworkに関する回答があることは知っていますが、私の問題に対する解決策は見つかりませんでした。

私は、認証といくつかの機能を持つアプリケーションを持っています。 私はそれに新しいアプリを追加し、それはDjango Rest Frameworkを使用します。私はこのアプリの中でだけライブラリを使用したい。また、私はPOSTリクエストを行いたいのですが、私はいつもこの応答を受け取ります。

{
    "detail": "CSRF Failed: CSRF token missing or incorrect."
}

次のようなコードがあります。

# urls.py
from django.conf.urls import patterns, url


urlpatterns = patterns(
    'api.views',
    url(r'^object/$', views.Object.as_view()),
)

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt


class Object(APIView):

    @csrf_exempt
    def post(self, request, format=None):
        return Response({'received data': request.data})

現在のアプリケーションに影響を与えることなく、APIを追加したい。 そこで質問なのですが、このアプリだけCSRFを無効にするにはどうすればいいのでしょうか?

解決方法を教えてください。

なぜこのエラーが発生するのですか?

この現象は、デフォルトの SessionAuthentication DRFが使用するスキーム。DRFの SessionAuthentication は、CSRF をチェックする必要がある認証に Django のセッションフレームワークを使用します。

を定義しない場合 authentication_classes は、この認証クラスをデフォルトとして使用します。

'DEFAULT_AUTHENTICATION_CLASSES'= (
    'rest_framework.authentication.SessionAuthentication',
    'rest_framework.authentication.BasicAuthentication'
),

DRFは、同じビューに対してセッションベースと非セッションベースの両方の認証をサポートする必要があるため、認証されたユーザーのみに対してCSRFチェックを実施します。つまり、認証されたリクエストだけが CSRF トークンを必要とし、匿名のリクエストは CSRF トークンなしで送信される可能性があります。

AJAXスタイルのAPIをSessionAuthenticationで使用している場合、以下のようなHTTPメソッド呼び出しに有効なCSRFトークンを含める必要があります。 PUT, PATCH, POST or DELETE リクエストに対応します。

では、どうすればいいのでしょうか?

csrfチェックを無効にするには、カスタム認証クラスを作成します。 CsrfExemptSessionAuthentication を継承したもので、デフォルトの SessionAuthentication クラスがあります。この認証クラスでは enforce_csrf() の内部で行われていたチェックを、実際の SessionAuthentication .

from rest_framework.authentication import SessionAuthentication, BasicAuthentication 

class CsrfExemptSessionAuthentication(SessionAuthentication):

    def enforce_csrf(self, request):
        return  # To not perform the csrf check previously happening

ビューの中で authentication_classes とする。

authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication)

これでcsrfのエラーに対処できるはずです。