私は Django-CSRF検証失敗 およびDjangoおよびPOSTメソッドに関連するいくつかの質問(および回答))を読みました。 best-but-not-working-for-meの答えは https://stackoverflow.com/a/4707639/755319
承認された回答はすべて、少なくとも3つのことを示唆しています。
提案どおり正確に実行しましたが、まだエラーが表示されました。私はDjango 1.3.1(ubuntu 12.04リポジトリから)とpython 2.7(ubuntuからのデフォルト)を使用しています)
これは私の見解です:
# Create your views here.
from Django.template import RequestContext
from Django.http import HttpResponse
from Django.shortcuts import render_to_response
from models import BookModel
def index(request):
return HttpResponse('Welcome to the library')
def search_form(request):
return render_to_response('library/search_form.html')
def search(request):
if request.method=='POST':
if 'q' in request.POST:
q=request.POST['q']
bookModel = BookModel.objects.filter(title__icontains=q)
result = {'books' : bookModel,}
return render_to_response('library/search.html', result, context_instance=RequestContext(request))
else:
return search_form(request)
else:
return search_form(request)
これは私のテンプレートです(search_form.html):
{% extends "base.html" %}
{% block content %}
<form action="/library/search/" method="post">
{% csrf_token %}
<input type="text" name="q">
<input type="submit" value="Search">
</form>
{% endblock %}
サーバーを再起動しましたが、403 forbiddenエラーがまだあり、CSRF検証が失敗したことを通知しています。
2つの質問があります。
RequestContextをsearch_formビューのrender_to_responseに配置してみてください。
context_instance=RequestContext(request)
私は間違っているかもしれませんが、上記の解決策はかなり複雑だと思いました。
私にとってうまくいったのは、単に私のcsrfトークンを私の投稿リクエストに含めることでした。
$.ajax({
type: "POST",
url: "/reports/",
data: { csrfmiddlewaretoken: "{{ csrf_token }}", // < here
state:"inactive"
},
success: function() {
alert("pocohuntus")
console.log("prototype")
}
})
このような問題を回避する最も簡単な方法は、 render
ショートカットを使用することです。
from Django.shortcuts import render
# .. your other imports
def search_form(request):
return render(request, 'library/search_form.html')
def search(request):
q = request.GET.get('q')
results = BookModel.objects.all()
if q:
results = results.filter(title__icontains=q)
return render(request, 'library/search.html', {'result': results})
この回答は、将来同じ問題が発生する可能性のある人を対象としています。
Djangoのフォームに必要なCSRF {{csrf_token}}
テンプレートタグは、クロスサイトリクエストフォージェリを防止します。CSRFにより、クライアントのブラウザがアクセスした悪意のあるサイトがDjangoによって提供されるcsrf_tokenは、Djangoサーバーとサイトがこのタイプの悪意のある攻撃から保護されることを簡単にします。あなたのフォームはcsrf_tokenで保護されていません、Djangoは403禁止ページを返します。これは、特にトークンが意図的に省略されていない場合のWebサイトの保護のフォームです。
しかし、Djangoサイトがcsrf_tokenを使用してフォームを保護したくない場合があります。たとえば、USSDアプリケーションを開発し、POSTリクエスト。POSTリクエストはクライアントのフォームからのものではないため、悪意のあるサイトがリクエストを送信できないため、CSRFのリスクは不可能です。 POSTリクエストは、フォームが送信されたときではなく、ユーザーがUSSDコードをダイヤルしたときに受信されます。
言い換えると、関数がPOSTリクエストを取得する必要があり、{{csrf_token}}が必要ない場合があります。
Djangoはデコレータ@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')
Djangoは、{{csrf_token}}
を使用して同じ機能を実行する別のデコレータも提供しますが、着信リクエストを拒否しません。このデコレータは@requires_csrf_token
です。例えば:
@requires_csrf_token
def my_view(request):
c = {}
# ...
return render(request, "a_template.html", c)
この投稿で言及する最後のデコレータは{{csrf_token}}とまったく同じで、@csrf_protect
と呼ばれます。ただし、このデコレーターを単独で使用することは、ビューに追加し忘れることがあるため、ベストプラクティスではありません。例えば:
@csrf_protect
def my_view(request):
c = {}
# ...
return render(request, "a_template.html", c)
以下は、より適切にガイドおよび説明するリンクです。
https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#module-Django.views.decorators.csrf
https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/
http://www.squarefree.com/securitytips/web-developers.html#CSRF
応答は403 bcozです。Djangoは、すべてのPOSTリクエストでcsrfトークン(投稿データに含まれる)を必要とします)。
これを行うには、次のようなさまざまな方法があります。
クッキーからトークンを取得する方法は、記事で説明されています ここにリンクの説明を入力してください
または
テンプレートで利用可能な{{csrf_token}}を使用してDOMからアクセスできます
したがって、2番目の方法を使用します。
var post_data = {
...
'csrfmiddlewaretoken':"{{ csrf_token }}"
...
}
$.ajax({
url:'url',
type:'POST'
data:post_data,
success:function(data){
console.log(data);
},
error:function(error){
console.log(error);
}
});
あなたも使うことができます
direct_to_template(request, 'library/search.html', result)
の代わりに
render_to_response('library/search.html', result, context_instance=RequestContext(request))
direct_to_template
は自動的にRequestContext
を追加します。ただし、direct_to_template
は非推奨となり、Djangoが代わりにCBV TemplateView
を使用することを提案します。
RequestContext
を使用すると、コンテキストプロセッサを使用できます。そして、これはあなたの間違いです:{% csrf_token %}
空の文字列を出力し、403を取得しました。
応答にはRequestContext
を使用する必要があります
たとえばview.py
ファイル
from Django.template import RequestContext
def home(request):
return render_to_response('home.html',RequestContext(request, {}))