Saya ingin membuat POST request
dev lokal saya, seperti ini:
HTTParty.post('http://localhost:3000/fetch_heroku',
:body => {:type => 'product'},)
Namun, dari konsol server itu melaporkan
Started POST "/fetch_heroku" for 127.0.0.1 at 2016-02-03 23:33:39 +0800
ActiveRecord::SchemaMigration Load (0.0ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by AdminController#fetch_heroku as */*
Parameters: {"type"=>"product"}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms
Ini pengontrol dan pengaturan rute saya, ini cukup sederhana.
def fetch_heroku
if params[:type] == 'product'
flash[:alert] = 'Fetch Product From Heroku'
Heroku.get_product
end
end
post 'fetch_heroku' => 'admin#fetch_heroku'
Saya tidak yakin apa yang harus saya lakukan? Untuk mematikan CSRF pasti akan berhasil, tetapi saya pikir itu adalah kesalahan saya saat membuat API semacam itu.
Apakah ada penyiapan lain yang perlu saya lakukan?
ruby-on-rails
cqcn1991
sumber
sumber
protect_from_forgery with: :null_session
.Jawaban:
Pemalsuan permintaan lintas situs (CSRF / XSRF) adalah ketika halaman web jahat menipu pengguna agar melakukan permintaan yang tidak dimaksudkan, misalnya dengan menggunakan bookmarklet, iframe, atau hanya dengan membuat halaman yang secara visual cukup mirip untuk menipu pengguna.
The perlindungan Rails CSRF dibuat untuk "klasik" web apps - itu hanya memberikan tingkat jaminan bahwa permintaan berasal dari aplikasi web Anda sendiri. Token CSRF berfungsi seperti rahasia yang hanya diketahui oleh server Anda - Rails menghasilkan token acak dan menyimpannya dalam sesi. Formulir Anda mengirim token melalui input tersembunyi dan Rails memverifikasi bahwa permintaan non GET apa pun menyertakan token yang cocok dengan apa yang disimpan dalam sesi.
Namun API biasanya menurut definisi lintas situs dan dimaksudkan untuk digunakan di lebih dari aplikasi web Anda, yang berarti bahwa seluruh konsep CSRF tidak cukup berlaku.
Sebagai gantinya, Anda harus menggunakan strategi berbasis token untuk mengautentikasi permintaan API dengan kunci dan rahasia API karena Anda memverifikasi bahwa permintaan tersebut berasal dari klien API yang disetujui - bukan dari aplikasi Anda sendiri.
Anda dapat menonaktifkan CSRF seperti yang ditunjukkan oleh @dcestari:
class ApiController < ActionController::Base protect_from_forgery with: :null_session end
Diperbarui. Di Rails 5 Anda dapat membuat aplikasi hanya API dengan menggunakan
--api
opsi:rails new appname --api
Mereka tidak menyertakan middleware CSRF dan banyak komponen lain yang superflouus.
sumber
Cara lain untuk mematikan CSRF yang tidak akan membuat sesi null adalah dengan menambahkan:
skip_before_action :verify_authenticity_token
di Rails Controller Anda. Ini akan memastikan Anda masih memiliki akses ke info sesi.
Sekali lagi, pastikan Anda hanya melakukan ini di pengontrol API atau di tempat lain di mana perlindungan CSRF tidak cukup berlaku.
sumber
protect_from_forgery except: [:my_method_name]
?Ada info yang relevan tentang konfigurasi CSRF sehubungan dengan pengontrol API di api.rubyonrails.org :
sumber
protect_from_forgery
masih diperlukan untuk API, dan sumber yang mengatakan bahwa itu tidak. Bagaimana jika API untuk aplikasi satu halaman, yang menggunakan cookie sesi untuk otentikasi pengguna?Sejak Rails 5 Anda juga dapat membuat kelas baru dengan :: API, bukan :: Base:
class ApiController < ActionController::API end
sumber
Jika Anda ingin mengecualikan tindakan sampel pengontrol sampel
class TestController < ApplicationController protect_from_forgery :except => [:sample] def sample render json: @hogehoge end end
Anda dapat memproses permintaan dari luar tanpa masalah.
sumber
Solusi paling sederhana untuk masalah ini adalah melakukan hal-hal standar di pengontrol Anda atau Anda dapat langsung memasukkannya ke ApplicationController
class ApplicationController < ActionController::Base protect_from_forgery with: :exception, prepend: true end
sumber
Jika Anda hanya ingin melewatkan proteksi CSRF untuk satu atau lebih aksi pengontrol (bukan seluruh pengontrol), coba ini
skip_before_action :verify_authenticity_token, only [:webhook, :index, :create]
Di mana
[:webhook, :index, :create]
akan melewati pemeriksaan untuk 3 tindakan tersebut, tetapi Anda dapat mengubah ke mana saja yang ingin Anda lewatisumber