Django CSRFCookieが設定されていません


86

しばらくの間問題が発生しました。CSRFCookieが設定されていません。以下のコードをご覧ください

Python

def deposit(request, account_num):
    if request.method == 'POST':
        account = get_object_or_404(account_info, acct_number=account_num)
        form_ = AccountForm(request.POST or None, instance=account)
        form = BalanceForm(request.POST)
        info = str(account_info.objects.filter(acct_number=account_num))
        inf = info.split()
        
        if form.is_valid():

            # cd=form.cleaned_data
            now = datetime.datetime.now()
            cmodel = form.save()
            cmodel.acct_number = account_num
            
            # RepresentsInt(cmodel.acct_number)
            cmodel.bal_change = "%0.2f" % float(cmodel.bal_change)
            cmodel.total_balance = "%0.2f" % (float(inf[1]) + float(cmodel.bal_change))
            account.balance = "%0.2f" % float(cmodel.total_balance)
            cmodel.total_balance = "%0.2f" % float(cmodel.total_balance)
            
            # cmodel.bal_change=cmodel.bal_change
            cmodel.issued = now.strftime("%m/%d/%y %I:%M:%S %p")
            account.recent_change = cmodel.issued
            cmodel.save()
            account.save()
            
            return HttpResponseRedirect("/history/" + account_num + "/")
        
        else:
            return render_to_response('history.html',
                                      {'account_form': form},
                                      context_instance=RequestContext(request))

HTMLではここにコードがあります

HTML

<form action="/deposit/{{ account_num }}/" method="post">
    <table>
        <tr>
            {{ account_form.bal_change }}
            &nbsp;
            <input type="submit" value="Deposit"/>
        </tr>
        {% csrf_token %}
    </table>
</form>

スタックしました。すでにCookieをクリアし、他のブラウザを使用しましたが、csrfcookieが設定されていません。


あなたはCsrfViewMiddlewareあなたのMIDDLEWARE_CLASSES設定にありますか?
alecxe 2013

{%csrf_token%}テンプレートにフォームを追加します。
ローハン2013

4
@Rohanすでにあります、質問を参照してください。
alecxe 2013

1
はい、私はすでにCsrfViewMiddlewareを持っており、フォームにcsrf_tokenをすでに持っています

私はDjangocorsモジュールを使用していて、ReactJSを介してアクセスしています。(どちらもローカルホスト上にありました)。私もこのOPの問題を抱えていました。credentials: 'include'POSTリクエストに追加してから、djangoのsettings.py:もCORS_ALLOW_CREDENTIALS = True追加@csrf_exemptすると、ビューに追加しなくても問題が修正されたようです。実際にはドキュメントにあります... pypi.org/project/django-cors-headers-multi *これが上記の質問の1つに関連していることは知っていますが、まだコメントできず、他の誰かの時間を節約したいと思っています。 tを見つけるために私を連れて行った
DW

回答:


134

これは、CSRF_COOKIE_SECURE = Trueが設定されていて、サイトに安全にアクセスしていない場合、またはCSRF_COOKIE_HTTPONLY = Trueここここに記載されているように設定されている場合にも発生する可能性があります。


10
ありがとう!同じことがSESSION_COOKIE_SECURE = True
nonameSL 2018

74
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt 
def your_view(request):
    if request.method == "POST":
        # do something
    return HttpResponse("Your response")

61
セキュリティメカニズムを完全に無効にすることは、エラーを修正するための良い方法ではありません。
ギヨームアルギス2016年

2
2017年にcookiecutter-djangoを使用している場合、これは本番環境での正解です。
アンドレドゥアルテ2017年

1
なぜそれは好奇心からですか?
パトリックギャラガー

3
この回答は、「セキュリティメカニズムを完全に無効にする」ことを示唆するものではなく、CSRFトークンを使用できない可能性がある単一のケースに対してそれを行う方法を示しているだけです。これは私の場合で、外部クライアントにPOSTアクションを提供する必要があります。
mariotomo

これは、UIからcsrfトークンを提供できない開発段階で使用するTODOの種類のアイテムです。ただし、ライブアプリにはお勧めできません。
アマンマダン

24

HTML5 Fetch APIを使用してログインユーザーとしてPOSTリクエストを行い、を取得Forbidden (CSRF cookie not set.)している場合fetchは、デフォルトでセッションCookieが含まれていないため、Djangoはページを読み込んだユーザーとは別のユーザーであると見なしている可能性があります。 。

credentials: 'include'フェッチするオプションを渡すことにより、セッショントークンを含めることができます。

var csrftoken = getCookie('csrftoken');
var headers = new Headers();
headers.append('X-CSRFToken', csrftoken);
fetch('/api/upload', {
    method: 'POST',
    body: payload,
    headers: headers,
    credentials: 'include'
})

インスタンス化したHeader()メソッドを教えてください。そのグローバルjavascriptメソッドですか?
Abz Rockers 2018

@AbzRockers:はい、HeadersHTML5 FetchAPIの一部であるグローバルJavaScriptインターフェースです。developer.mozilla.org/en-US/docs/Web/API/Headers
user85461

13

この あなたは追加することによって、それを解決することができensure_csrf_cookieデコレータをあなたのビューに

from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def yourView(request):
 #...

この方法が機能しない場合。ミドルウェアでcsrfにコメントしようとします。もう一度テストします。


5

DRFを使用しているときに同様の状況に遭遇しました。解決策は、urls.pyのビューに.as_view()メソッドを追加することでした。


コードも含めたほうがいいでしょう
AlexJolig19年

1
@AlexJoligも同じ問題に直面しました。問題は.as_view()、ApiViewを後から追加するのを忘れたため、コードがどのように見える urlpatterns += path('resource', ResourceView)かということurlpatterns += path('resource', ResourceView.as_view())
でした

4

DRFを使用している場合は、urlpatternsが正しいかどうかを確認してください。忘れている可能性があります。 .as_view()

そのため、私のコードは次のようになりました。

urlpatterns += path('resource', ResourceView) 

そして、それはそれがどのようにあるべきかです:

urlpatterns += path('resource', ResourceView.as_view())

1

settings.pyにインストールされているかどうかを確認してください

 MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',)

テンプレートでは、データはcsrf_tokenでフォーマットされています。

<form>{% csrf_token %}
</form>

私はあなたのすべてのコードを持っていませんが、問題はここにあると信じています:defdeposit(request、account_num):それをdefdeposit(request)に変更しました:そしてaccount_numをコールバックする方法を見つけます。これで、account_numがテーブルフィールドであるか変数であるかによって異なります。
drabo2005 2013

これは変数{{account_num}}ですが、これはcsrfトークンにどのように影響しますか?

csrfトークンはリクエストのみを参照していると思うので、ここで変数を処理することはできません。djangoproject.comをチェックして、csrf_tokenに関する適切な回答を得ることができるかもしれません。
drabo2005 2013


1

これは、フォームアクションを設定しない場合にも発生します。
私にとっては、コードが次の場合にこのエラーが表示されていました。

<form class="navbar-form form-inline my-2 my-lg-0" role="search" method="post">

私が自分のコードをこれに修正したとき:

<form class="navbar-form form-inline my-2 my-lg-0" action="{% url 'someurl' %}" role="search" method="post">

私のエラーは消えました。


0

問題はあなたが扱っていないようです GET最初にフォームを取得せずに、リクエストを適切にか、データを直接投稿していないようです。

最初にページにアクセスすると、クライアントは送信します GETリクエストを送信します。その場合は、適切な形式でhtmlを送信する必要があります。

後で、ユーザーはフォームに記入して送信します POSTフォームに入力し、フォームデータリクエストをします。

あなたの見解は次のようになります。

def deposit(request,account_num):
   if request.method == 'POST':
      form_=AccountForm(request.POST or None, instance=account)
      if form.is_valid(): 
          #handle form data
          return HttpResponseRedirect("/history/" + account_num + "/")
      else:
         #handle when form not valid
    else:
       #handle when request is GET (or not POST)
       form_=AccountForm(instance=account)

    return render_to_response('history.html',
                          {'account_form': form},
                          context_instance=RequestContext(request))

0

ChromeのCookieがWebサイトのデフォルトオプションで設定されていることを確認してください。ローカルデータの設定を許可します(推奨)。


0

方法1:

from django.shortcuts import render_to_response
return render_to_response(
    'history.html',
    RequestContext(request, {
        'account_form': form,
    })

方法2:

from django.shortcuts import render
return render(request, 'history.html', {
    'account_form': form,
})

render_to_responseメソッドは、応答Cookieの問題を引き起こす可能性があるためです。


0

私は一度会ったばかりです、解決策はクッキーを空にすることです。また、SECRET_KEY関連のデバッグ中に変更される場合があります。


0

ブラウザのキャッシュをクリアすると、この問題が修正されました。別のプロジェクトが発生したときに作業した後、ローカル開発環境を切り替えてdjango-blog-zinniaチュートリアルを実行していました。最初は、チュートリアルに合わせてINSTALLED_APPSの順序を変更したことが原因だと思っていましたが、これらを元に戻し、キャッシュをクリアするまで修正できませんでした。


0

以前はDjango1.10を使用していたので、この問題に直面していました。今、私はそれをDjango 1.9にダウングレードしました、そしてそれはうまく働いています。


1.10.3を使用すると、この問題が発生しました。1.10.6にアップグレードすると、修正されました。
Mike Darmetko 2017年

0

同じエラーが発生しました。私の場合、method_decoratorを追加すると次のようになります。

from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator

method_decorator(csrf_protect)
def post(self, request):
    ...

0

djangoセッションバックエンドがsettings.pyで正しく構成されていることを確認してください。次に、これを試してください、

class CustomMiddleware(object):
  def process_request(self,request:HttpRequest):
      get_token(request)

このミドルウェアをdjangoのバージョンのsettings.pyMIDDLEWARE_CLASSESまたはそれにMIDDLEWARE応じて追加します

get_token-POSTフォームに必要なCSRFトークンを返します。トークンは英数字の値です。まだ設定されていない場合は、新しいトークンが作成されます。


-4

あなたの見解では、csrfデコレータを使用していますか?

from django.views.decorators.csrf import csrf_protect

@csrf_protect def view(request, params): ....

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.