Ich möchte POST request
meinem lokalen Entwickler Folgendes mitteilen:
HTTParty.post('http://localhost:3000/fetch_heroku',
:body => {:type => 'product'},)
Über die Serverkonsole wird jedoch berichtet
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
Hier ist mein Controller und Routen-Setup, es ist ganz einfach.
def fetch_heroku
if params[:type] == 'product'
flash[:alert] = 'Fetch Product From Heroku'
Heroku.get_product
end
end
post 'fetch_heroku' => 'admin#fetch_heroku'
Ich bin mir nicht sicher, was ich tun muss? Das Ausschalten der CSRF würde sicherlich funktionieren, aber ich denke, es sollte mein Fehler sein, wenn ich eine solche API erstelle.
Muss ich noch etwas einrichten?
ruby-on-rails
cqcn1991
quelle
quelle
protect_from_forgery with: :null_session
.Antworten:
Cross Site Request Forgery (CSRF / XSRF) ist, wenn eine böswillige Webseite Benutzer dazu verleitet, eine Anforderung auszuführen, die nicht beabsichtigt ist, z. B. mithilfe von Lesezeichen, Iframes oder einfach durch Erstellen einer Seite, die visuell ähnlich genug ist, um Benutzer zu täuschen.
Der Rails CSRF-Schutz wurde für "klassische" Web-Apps entwickelt. Er bietet lediglich ein gewisses Maß an Sicherheit, dass die Anforderung von Ihrer eigenen Web-App stammt. Ein CSRF-Token funktioniert wie ein Geheimnis, das nur Ihr Server kennt. Rails generiert ein zufälliges Token und speichert es in der Sitzung. Ihre Formulare senden das Token über eine versteckte Eingabe, und Rails überprüft, ob jede Nicht-GET-Anforderung ein Token enthält, das mit dem übereinstimmt, was in der Sitzung gespeichert ist.
Eine API ist jedoch in der Regel per Definition standortübergreifend und soll in mehr als Ihrer Web-App verwendet werden. Dies bedeutet, dass das gesamte Konzept von CSRF nicht ganz anwendbar ist.
Stattdessen sollten Sie eine tokenbasierte Strategie zur Authentifizierung von API-Anforderungen mit einem API-Schlüssel und einem Geheimnis verwenden, da Sie überprüfen, ob die Anforderung von einem genehmigten API-Client stammt - nicht von Ihrer eigenen App.
Sie können CSRF deaktivieren, wie von @dcestari angegeben:
class ApiController < ActionController::Base protect_from_forgery with: :null_session end
Aktualisiert. In Rails 5 können Sie mithilfe der folgenden
--api
Option nur API-Anwendungen generieren :rails new appname --api
Sie enthalten nicht die CSRF-Middleware und viele andere Komponenten, die überflüssig sind.
quelle
Eine andere Möglichkeit, CSRF zu deaktivieren, die keine Nullsitzung rendert, besteht darin, Folgendes hinzuzufügen:
skip_before_action :verify_authenticity_token
in Ihrem Rails Controller. Dadurch wird sichergestellt, dass Sie weiterhin Zugriff auf Sitzungsinformationen haben.
Stellen Sie erneut sicher, dass Sie dies nur in API-Controllern oder an anderen Orten tun, an denen der CSRF-Schutz nicht vollständig angewendet wird.
quelle
protect_from_forgery except: [:my_method_name]
?Auf api.rubyonrails.org finden Sie relevante Informationen zu einer Konfiguration von CSRF in Bezug auf API-Controller :
quelle
protect_from_forgery
dies für APIs noch erforderlich ist, und Quellen, die besagen, dass dies nicht der Fall ist. Was ist, wenn die API für eine App mit nur einer Seite vorgesehen ist, die das Sitzungscookie für die Benutzerauthentifizierung verwendet?Seit Rails 5 können Sie auch eine neue Klasse mit :: API anstelle von :: Base erstellen :
class ApiController < ActionController::API end
quelle
Wenn Sie die Beispielaktion des Sample-Controllers ausschließen möchten
class TestController < ApplicationController protect_from_forgery :except => [:sample] def sample render json: @hogehoge end end
Sie können Anfragen von außen problemlos bearbeiten.
quelle
Die einfachste Lösung für das Problem besteht darin, Standardaufgaben in Ihrem Controller zu erledigen, oder Sie können sie direkt in ApplicationController einfügen
class ApplicationController < ActionController::Base protect_from_forgery with: :exception, prepend: true end
quelle