Saya dapat menggunakan beberapa bantuan yang sesuai dengan mekanisme perlindungan CSRF Django melalui pos AJAX saya. Saya telah mengikuti petunjuk di sini:
http://docs.djangoproject.com/en/dev/ref/contrib/csrf/
Saya telah menyalin kode sampel AJAX yang mereka miliki di halaman itu dengan tepat:
http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
Saya memasang peringatan mencetak konten getCookie('csrftoken')
sebelum xhr.setRequestHeader
panggilan dan memang diisi dengan beberapa data. Saya tidak yakin bagaimana memverifikasi bahwa token itu benar, tetapi saya didorong bahwa itu menemukan dan mengirim sesuatu.
Tapi Django masih menolak posting AJAX saya.
Ini JavaScript saya:
$.post("/memorize/", data, function (result) {
if (result != "failure") {
get_random_card();
}
else {
alert("Failed to save card data.");
}
});
Inilah kesalahan yang saya lihat dari Django:
[23 / Feb / 2011 22:08:29] "POST / memorize / HTTP / 1.1" 403 2332
Saya yakin saya kehilangan sesuatu, dan mungkin itu sederhana, tetapi saya tidak tahu apa itu. Saya telah mencari di sekitar SO dan melihat beberapa informasi tentang mematikan cek CSRF untuk pandangan saya melaluicsrf_exempt
dekorator, tetapi saya menemukan itu tidak menarik. Saya sudah mencobanya dan berhasil, tetapi saya lebih suka mendapatkan POST saya untuk bekerja dengan cara yang dirancang Django untuk mengharapkannya, jika memungkinkan.
Untuk berjaga-jaga jika ini membantu, inilah intisari dari pandangan saya:
def myview(request):
profile = request.user.profile
if request.method == 'POST':
"""
Process the post...
"""
return HttpResponseRedirect('/memorize/')
else: # request.method == 'GET'
ajax = request.GET.has_key('ajax')
"""
Some irrelevent code...
"""
if ajax:
response = HttpResponse()
profile.get_stack_json(response)
return response
else:
"""
Get data to send along with the content of the page.
"""
return render_to_response('memorize/memorize.html',
""" My data """
context_instance=RequestContext(request))
Terima kasih atas balasan Anda!
Jawaban:
Solusi nyata
Oke, saya berhasil melacak masalahnya. Itu terletak pada kode Javascript (seperti yang saya sarankan di bawah).
Yang Anda butuhkan adalah ini:
alih-alih kode yang diposting di dokumen resmi: https://docs.djangoproject.com/en/2.2/ref/csrf/
Kode yang berfungsi, berasal dari entri Django ini: http://www.djangoproject.com/weblog/2011/feb/08/security/
Jadi solusi umumnya adalah: "gunakan handler ajaxSetup bukan ajaxSend handler". Saya tidak tahu mengapa itu berhasil. Tapi hal ini bekerja untukku :)
Posting sebelumnya (tanpa jawaban)
Sebenarnya saya mengalami masalah yang sama.
Itu terjadi setelah memperbarui ke Django 1.2.5 - tidak ada kesalahan dengan permintaan POST AJAX di Django 1.2.4 (AJAX tidak dilindungi dengan cara apa pun, tetapi bekerja dengan baik).
Sama seperti OP, saya telah mencoba cuplikan JavaScript yang diposting di dokumentasi Django. Saya menggunakan jQuery 1.5. Saya juga menggunakan middleware "django.middleware.csrf.CsrfViewMiddleware".
Saya mencoba mengikuti kode middleware dan saya tahu itu gagal pada ini:
lalu
ini "jika" benar, karena "request_csrf_token" kosong.
Pada dasarnya itu berarti bahwa header TIDAK diatur. Jadi apakah ada yang salah dengan garis JS ini:
?
Saya harap detail yang disediakan akan membantu kami menyelesaikan masalah :)
sumber
ajaxSetup
daripadaajaxSend
menjalankan counter ke dokumen jQuery: api.jquery.com/jQuery.ajaxSetupJika Anda menggunakan
$.ajax
fungsi ini, Anda bisa menambahkancsrf
token di badan data:sumber
<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
csrfmiddlewaretoken: '{{ csrf_token }}'
kedata
kamus saya melalui$.post
telepon.Tambahkan baris ini ke kode jQuery Anda:
dan dilakukan.
sumber
CSRF Failed: CSRF token missing or incorrect.
Masalahnya adalah karena Django mengharapkan nilai dari cookie akan dikembalikan sebagai bagian dari data formulir. Kode dari jawaban sebelumnya adalah mendapatkan javascript untuk mencari nilai cookie dan memasukkannya ke dalam formulir data. Itu cara yang indah untuk melakukannya dari sudut pandang teknis, tetapi memang terlihat sedikit verbose.
Di masa lalu, saya telah melakukannya lebih sederhana dengan mendapatkan javascript untuk memasukkan nilai token ke dalam data posting.
Jika Anda menggunakan {% csrf_token%} di templat Anda, Anda akan mendapatkan bidang formulir tersembunyi yang dipancarkan yang membawa nilainya. Tetapi, jika Anda menggunakan {{csrf_token}} Anda hanya akan mendapatkan nilai telanjang token, sehingga Anda dapat menggunakan ini dalam javascript seperti ini ....
Kemudian Anda bisa memasukkan itu, dengan nama kunci yang diperlukan dalam hash Anda kemudian kirimkan sebagai data ke panggilan ajax.
sumber
window
objek, sehingga mereka dapat diakses sesudahnya. Bahkan dalam file statis.The
{% csrf_token %}
put di html template dalam<form></form>
diterjemahkan menjadi sesuatu seperti:
jadi mengapa tidak hanya mengambilnya di JS Anda seperti ini:
dan kemudian meneruskannya mis melakukan POST, seperti:
sumber
Jawaban non-jquery:
pemakaian:
sumber
Jika form Anda memposting dengan benar di Django tanpa JS, Anda harus dapat meningkatkannya secara progresif dengan ajax tanpa ada peretasan atau pengalihan csrf token yang berantakan. Serialkan seluruh formulir dan itu akan secara otomatis mengambil semua bidang formulir Anda termasuk bidang csrf tersembunyi:
Saya sudah menguji ini dengan Django 1.3+ dan jQuery 1.5+. Jelas ini akan bekerja untuk semua bentuk HTML, bukan hanya aplikasi Django.
sumber
Gunakan Firefox dengan Firebug. Buka tab 'Konsol' sambil menjalankan permintaan ajax. Dengan
DEBUG=True
Anda mendapatkan halaman kesalahan django yang bagus sebagai respons dan Anda bahkan dapat melihat html yang diberikan dari respons ajax di tab konsol.Maka Anda akan tahu apa kesalahannya.
sumber
Jawaban yang diterima kemungkinan besar adalah herring merah. Perbedaan antara Django 1.2.4 dan 1.2.5 adalah persyaratan untuk token CSRF untuk permintaan AJAX.
Saya menemukan masalah ini pada Django 1.3 dan itu disebabkan oleh cookie CSRF yang tidak disetel di tempat pertama. Django tidak akan mengatur cookie kecuali jika harus. Jadi situs eksklusif atau sangat ajax yang berjalan pada Django 1.2.4 berpotensi tidak akan pernah mengirim token ke klien dan kemudian peningkatan yang memerlukan token akan menyebabkan 403 kesalahan.
Perbaikan yang ideal ada di sini: http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#page-uses-ajax-without-any-html-form
tetapi Anda harus menunggu 1,4 kecuali ini hanya dokumentasi yang mengejar kode
Edit
Perhatikan juga bahwa dokumen Django nanti mencatat bug di jQuery 1.5 jadi pastikan Anda menggunakan 1.5.1 atau lebih baru dengan kode yang disarankan Django: http://docs.djangoproject.com/en/1.3/ref/contrib/csrf/# ajax
sumber
ensure_csrf_cookie
bahwa Anda dapat membungkus tampilan untuk memastikan mengirimkan cookie.csrftoken
cookie di tempat pertama, terima kasih!Sepertinya tidak ada yang menyebutkan cara melakukan ini di JS murni menggunakan
X-CSRFToken
header dan{{ csrf_token }}
, jadi inilah solusi sederhana di mana Anda tidak perlu mencari melalui cookie atau DOM:sumber
Karena tidak dinyatakan di mana pun dalam jawaban saat ini, solusi tercepat jika Anda tidak menanamkan js ke template Anda adalah:
Masukkan
<script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script>
sebelum referensi Anda ke file script.js di template Anda, lalu tambahkancsrfmiddlewaretoken
kedata
kamus Anda di file js Anda:sumber
Saya baru saja mengalami situasi yang sedikit berbeda tetapi serupa. Tidak 100% yakin apakah itu akan menjadi resolusi untuk kasus Anda, tapi saya menyelesaikan masalah untuk Django 1.3 dengan menetapkan parameter POST 'csrfmiddlewaretoken' dengan string nilai cookie yang tepat yang biasanya dikembalikan dalam bentuk HTML rumah Anda oleh Django sistem template dengan tag '{% csrf_token%}'. Saya tidak mencoba pada Django yang lebih lama, hanya terjadi dan diselesaikan pada Django1.3. Masalah saya adalah bahwa permintaan pertama yang diajukan melalui Ajax dari formulir berhasil dilakukan tetapi upaya kedua dari yang sama persis dari gagal, menghasilkan status 403 meskipun tajuk 'X-CSRFToken' ditempatkan dengan benar dengan nilai token CSRF juga seperti dalam kasus upaya pertama. Semoga ini membantu.
Salam,
Hiro
sumber
Anda dapat menempelkan js ini ke file html Anda, ingat taruh sebelum fungsi js lainnya
sumber
Satu token CSRF ditugaskan untuk setiap sesi (yaitu setiap kali Anda masuk). Jadi sebelum Anda ingin mendapatkan beberapa data yang dimasukkan oleh pengguna dan mengirimkannya sebagai panggilan ajax ke beberapa fungsi yang dilindungi oleh dekorator csrf_protect, cobalah untuk menemukan fungsi yang dipanggil sebelum Anda mendapatkan data ini dari pengguna. Misalnya, beberapa templat harus dirender tempat pengguna Anda memasukkan data. Template itu sedang dibuat oleh beberapa fungsi. Dalam fungsi ini Anda bisa mendapatkan token csrf sebagai berikut: csrf = request.COOKIES ['csrftoken'] Sekarang berikan nilai csrf ini dalam kamus konteks terhadap template yang dimaksud sedang dirender. Sekarang dalam templat itu tulis baris ini: Sekarang dalam fungsi javascript Anda, sebelum membuat permintaan ajax, tulis ini: var csrf = $ ('# csrf'). val () ini akan memilih nilai token yang diteruskan ke templat dan menyimpannya dalam variabel csrf. Sekarang saat melakukan panggilan ajax, dalam data posting Anda, sampaikan nilai ini juga: "csrfmiddlewaretoken": csrf
Ini akan berfungsi bahkan jika Anda tidak menerapkan formulir Django.
Sebenarnya, logika di sini adalah: Anda perlu token yang bisa Anda dapatkan dari permintaan. Jadi, Anda hanya perlu mencari tahu fungsi yang dipanggil segera setelah masuk. Setelah Anda memiliki token ini, buat panggilan ajax lain untuk mendapatkannya atau kirimkan ke beberapa templat yang dapat diakses oleh ajax Anda.
sumber
csrftoken: csrftoken
daripadacsrfmiddlwaretoken: csrftoken
. Setelah perubahan, itu berhasil. Terima kasihuntuk seseorang yang menemukan ini dan sedang mencoba melakukan debug:
1) cek csrf Django (dengan asumsi Anda mengirim satu) ada di sini
2) Dalam kasus saya,
settings.CSRF_HEADER_NAME
disetel ke 'HTTP_X_CSRFTOKEN' dan panggilan AJAX saya mengirim header bernama 'HTTP_X_CSRF_TOKEN' sehingga semuanya tidak berfungsi. Saya bisa mengubahnya di panggilan AJAX, atau pengaturan Django.3) Jika Anda memilih untuk mengubahnya di sisi server, cari lokasi pemasangan django dan letakkan breakpoint di
csrf middleware
.f yang Anda gunakanvirtualenv
, itu akan menjadi seperti:~/.envs/my-project/lib/python2.7/site-packages/django/middleware/csrf.py
Kemudian, pastikan
csrf
token diambil dengan benar dari request.META4) Jika Anda perlu mengubah tajuk, dll - ubah variabel itu di file pengaturan Anda
sumber
Jika seseorang berjuang dengan aksioma untuk membuat pekerjaan ini, ini membantu saya:
Sumber: https://cbuelter.wordpress.com/2017/04/10/django-csrf-with-axios/
sumber
Dalam kasus saya masalahnya adalah dengan konfigurasi nginx yang telah saya salin dari server utama ke yang sementara dengan menonaktifkan https yang tidak diperlukan pada yang kedua dalam proses.
Saya harus mengomentari dua baris ini di konfigurasi untuk membuatnya bekerja lagi:
sumber
Berikut ini adalah solusi yang kurang tepat yang disediakan oleh Django:
Sumber: https://docs.djangoproject.com/en/1.11/ref/csrf/
sumber