多くの人と同じように、私も CSRF と Django を使用する際に多くの問題を抱えてきました。
コンテキストは次のとおりです:
- ユーザーがファイルをアップロードできる https Web サイトを作成しました -
この Web サイトを作成するために Django 1.4.2 を使用し
ました - 私が望むことを行うアプリ *file_manager* を作成しました
- 私は管理者の URL からのみこのアプリを使用する
で無効django.middleware.csrf.CsrfViewMiddleware
にするMIDDLEWARE_CLASSES
とsettings.py
、すべて正常に動作します。
Debian Squeeze のコマンド ラインで cURL を使用してテンプレートにファイルをアップロードできます。ファイルはサーバーにヒットしますが、問題ありません。
ただし、安全ではないようです。
だから私は有効django.middleware.csrf.CsrfViewMiddleware
にしました もう機能しません。CSRF検証に関するあらゆる種類のエラーが発生します。
私は通常の容疑者を排除したと信じています(少なくとも望んでいます):
- {% csrf_token %}
- RequestContext
- settings.pyCsrfViewMiddleware
プロセスに関連するすべてのファイル (私が願っています) の下にあります。
ビュー.py
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.template import Context, loader, RequestContext
from django.shortcuts import render, get_object_or_404, redirect, render_to_response
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
from django.views.decorators.csrf import csrf_exempt
from file_manager.models import MyClass
from file_manager.forms import MyClassForm
def index(request):
latest_file_list = MyClass.objects.order_by('-name')[:5]
context = Context({
'latest_file_list': latest_file_list,
})
return render(request, 'file_manager/index.html', context)
def list(request):
# Handle file upload
if request.method == 'POST':
form = MyClassForm(request.POST, request.FILES)
if form.is_valid():
newdoc = MyClass(name='testupl', filefield = request.FILES['docfile'], uploader='fcav')
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('file_manager.views.list'))
else:
form = MyClassForm() # A empty, unbound form
# Load documents for the list page
documents = MyClass.objects.all()
# Render list page with the documents and the form
con = {'documents': documents, 'form': form}
con.update(csrf(request))
return render_to_response(
'list.html',
con,
context_instance=RequestContext(request)
)
list.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Minimal Django File Upload Example</title>
</head>
<body>
<!-- List of uploaded documents -->
{% if documents %}
<ul>
{% for document in documents %}
<li><a href="{{ document.filefield.url }}">{{ document.filefield.name }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No documents.</p>
{% endif %}
<!-- Upload form. Note enctype attribute! -->
<form action="{% url list %}" method="post" enctype="multipart/form-data">{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload" /></p>
</form>
</body>
</html>
そして、ここに私のcurlリクエストがあります:
curl --cacert /home/fcav/apache.pem --user admin:password
-e "https://domain.com/admin/" -X POST
-F "docfile=@/home/fcav/Downloads/basket.csv"
https://domain.com/admin/file_manager/myclass/list/
リクエストで Cookie も送信しようとすることで、curl リクエストのさまざまなバリエーションを試しましたが、cURL がアップロードを処理する方法について完全に混乱していると思います。
CSRF Cookie が設定されていないか、CSRF 検証に失敗しただけです。
cURL と Django を十分に知っている人がいて、CSRF を無効にせずに自分の Web サイトにアップロードする方法についてのヒントを教えてくれれば、本当に感謝しています。
よろしく、フロリアン