Jika protect_from_forgery
opsi tersebut disebutkan dalam application_controller, maka saya bisa masuk dan melakukan permintaan GET, tetapi pada permintaan POST pertama Rails me-reset sesi, yang mengeluarkan saya.
Saya protect_from_forgery
mematikan opsi untuk sementara, tetapi ingin menggunakannya dengan Angular.js. Apakah ada cara untuk melakukan itu?
Jawaban:
Saya pikir membaca nilai CSRF dari DOM bukanlah solusi yang baik, itu hanya solusi.
Berikut ini adalah dokumen bentuk situs resmi angularJS http://docs.angularjs.org/api/ng.$http :
Ini solusi saya berdasarkan instruksi itu:
Pertama, atur cookie:
Kemudian, kita harus memverifikasi token pada setiap permintaan non-GET.
Karena Rails telah dibangun dengan metode yang serupa, kita bisa menimpanya untuk menambahkan logika kita:
sumber
Jika Anda menggunakan perlindungan CSRF Rails default (
<%= csrf_meta_tags %>
), Anda dapat mengonfigurasi modul Angular Anda seperti ini:Atau, jika Anda tidak menggunakan CoffeeScript (apa !?):
Jika suka, Anda dapat mengirim tajuk hanya pada permintaan non-GET dengan sesuatu seperti berikut:
Juga, pastikan untuk memeriksa jawaban HungYuHei , yang mencakup semua pangkalan di server daripada klien.
sumber
<%= csrf_meta_tags %>
. Saya pikir seharusnya ada cukup untuk menyebutkanprotect_from_forgery
saja. Apa yang harus dilakukan? Dokumen dasar harus berupa HTML biasa (saya di sini bukan orang yang memilih).protect_from_forgery
apa yang Anda katakan adalah "ketika kode JavaScript saya membuat permintaan Ajax, saya berjanji untuk mengirimX-CSRF-Token
header di yang sesuai dengan token CSRF saat ini." Untuk mendapatkan token ini, Rails menyuntikkannya ke DOM dengan<%= csrf_meta_token %>
dan mendapatkan isi tag meta dengan jQuery setiap kali ia membuat permintaan Ajax (driver Rails 3 UJS default melakukan ini untuk Anda). Jika Anda tidak menggunakan ERB, tidak ada cara untuk mendapatkan token saat ini dari Rails ke halaman dan / atau JavaScript - dan dengan demikian Anda tidak dapat menggunakanprotect_from_forgery
cara ini.csrf_meta_tags
setiap kali server menghasilkan respons, dan setiap kali tag ini berbeda dari yang sebelumnya. Jadi, tag ini unik untuk setiap permintaan. Pertanyaannya adalah: bagaimana aplikasi menerima tag ini untuk permintaan AJAX (tanpa sudut)? Saya menggunakan protect_from_forgery dengan permintaan POST jQuery, tidak pernah repot-repot mendapatkan token CSRF ini, dan itu berhasil. Bagaimana?jQuery.ajaxPrefilter
seperti yang ditunjukkan di sini: github.com/indirect/jquery-rails/blob/c1eb6ae/vendor/assets/… Anda dapat membaca dengan teliti file ini dan melihat semua simpanan Rails melompat untuk membuatnya berfungsi cukup banyak tanpa harus khawatirkan itu.put
danpost
bukannya padacommon
? Dari panduan keamanan rel :The solution to this is including a security token in non-GET requests
The angular_rails_csrf permata otomatis menambahkan dukungan untuk pola yang dijelaskan dalam jawaban HungYuHei ini untuk semua pengendali Anda:
sumber
angular_rails_csrf
permata tidak berfungsi dengan Rails 5. Namun, mengonfigurasi header permintaan Angular dengan nilai dari meta tag CSRF berfungsi!Jawaban yang menggabungkan semua jawaban sebelumnya dan itu bergantung bahwa Anda menggunakan
Devise
permata otentikasi.Pertama-tama, tambahkan permata:
Selanjutnya, tambahkan
rescue_from
blok ke application_controller.rb:Dan akhirnya, tambahkan modul interseptor ke aplikasi sudut Anda.
sumber
$injector
bukan hanya menyuntikkan langsung$http
?Saya melihat jawaban-jawaban lain dan berpikir mereka hebat dan dipikirkan dengan baik. Saya membuat aplikasi rel saya bekerja dengan apa yang saya pikir merupakan solusi yang lebih sederhana jadi saya pikir saya akan berbagi. Aplikasi rel saya datang dengan ini default di dalamnya,
Saya membaca komentar dan sepertinya itulah yang ingin saya gunakan angular dan menghindari kesalahan csrf. Saya mengubahnya menjadi ini,
Dan sekarang berhasil! Saya tidak melihat alasan mengapa ini tidak berhasil, tetapi saya ingin mendengar beberapa wawasan dari poster lain.
sumber
Saya telah menggunakan konten dari jawaban HungYuHei di aplikasi saya. Saya menemukan bahwa saya berurusan dengan beberapa masalah tambahan, beberapa karena penggunaan Devise untuk otentikasi, dan beberapa karena default yang saya dapatkan dengan aplikasi saya:
Saya perhatikan pertanyaan stack overflow terkait dan jawabannya di sana , dan saya menulis posting blog yang jauh lebih verbose yang merangkum berbagai pertimbangan. Bagian dari solusi yang relevan di sini adalah, di pengontrol aplikasi:
sumber
Saya menemukan peretasan yang sangat cepat untuk ini. Yang harus saya lakukan adalah sebagai berikut:
Sebuah. Dalam pandangan saya, saya menginisialisasi
$scope
variabel yang berisi token, katakanlah sebelum formulir, atau bahkan lebih baik pada inisialisasi pengontrol:b. Di pengontrol AngularJS saya, sebelum menyimpan entri baru saya, saya menambahkan token ke hash:
Tidak ada lagi yang perlu dilakukan.
sumber
Ini bekerja di sisi sudut!
sumber