Ik wil een POST request
doen aan mijn lokale ontwikkelaar, als volgt:
HTTParty.post('http://localhost:3000/fetch_heroku',
:body => {:type => 'product'},)
Vanaf de serverconsole rapporteert het echter
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 is mijn configuratie van de controller en routes, het is vrij eenvoudig.
def fetch_heroku
if params[:type] == 'product'
flash[:alert] = 'Fetch Product From Heroku'
Heroku.get_product
end
end
post 'fetch_heroku' => 'admin#fetch_heroku'
Ik weet niet zeker wat ik moet doen? De CSRF uitschakelen zou zeker werken, maar ik denk dat het mijn fout zou moeten zijn bij het maken van zo’n API.
Is er nog een andere instelling die ik moet doen?
Antwoord 1, autoriteit 100%
Cross-site request forgery (CSRF/XSRF) is wanneer een kwaadwillende webpagina gebruikers misleidt om een verzoek uit te voeren dat niet bedoeld is, bijvoorbeeld door bookmarklets, iframes te gebruiken of gewoon door een pagina te maken die visueel genoeg op elkaar lijkt om gebruikers voor de gek te houden.
De Rails CSRF-beschermingis gemaakt voor ” klassieke” web-apps – het geeft gewoon een zekere mate van zekerheid dat het verzoek afkomstig is van uw eigen web-app. Een CSRF-token werkt als een geheim dat alleen uw server kent – Rails genereert een willekeurig token en slaat het op in de sessie. Uw formulieren verzenden het token via een verborgen invoer en Rails verifieert dat elk niet-GET-verzoek een token bevat dat overeenkomt met wat is opgeslagen in de sessie.
Een API is echter meestal per definitie cross-site en bedoeld om in meer dan alleen uw web-app te worden gebruikt, wat betekent dat het hele concept van CSRF niet helemaal van toepassing is.
In plaats daarvan moet u een op tokens gebaseerde strategie gebruiken voor het verifiëren van API-verzoeken met een API-sleutel en geheim, aangezien u verifieert dat het verzoek afkomstig is van een goedgekeurde API-client en niet van uw eigen app.
Je kunt CSRF deactiveren zoals aangegeven door @dcestari:
class ApiController < ActionController::Base
protect_from_forgery with: :null_session
end
Bijgewerkt.In Rails 5 kun je API-only applicaties genereren door de --api
optie te gebruiken:
rails new appname --api
Ze bevatten niet de CSRF-middleware en vele andere componenten die overbodig zijn.
- http://guides.rubyonrails.org/security. html#cross-site-request-forgery-csrf
- https://labs.kollegorna.se/blog /2015/04/build-an-api-now/
- WAARSCHUWING: kan de authenticiteitsrails van CSRF-tokens niet verifiëren
Antwoord 2, autoriteit 74%
Een andere manier om CSRF uit te schakelen die geen null-sessie weergeeft, is door het volgende toe te voegen:
skip_before_action :verify_authenticity_token
in uw Rails-controller. Dit zorgt ervoor dat je nog steeds toegang hebt tot sessie-informatie.
Nogmaals, zorg ervoor dat u dit alleen doet in API-controllers of op andere plaatsen waar CSRF-beveiliging niet helemaal van toepassing is.
Antwoord 3, autoriteit 17%
Er is relevante informatie over een configuratie van CSRF met betrekking tot API-controllers op api.rubyonrails .org:
⋮
Het is belangrijk om te onthouden dat XML- of JSON-verzoeken ook worden beïnvloed en als u een APIu moet de beschermingsmethode tegen vervalsing wijzigen in
ApplicationController
(standaard::exception
):class ApplicationController < ActionController::Base protect_from_forgery unless: -> { request.format.json? } end
Misschien willen we CSRF-beveiliging voor API’s uitschakelen, omdat ze doorgaans zijn ontworpen om statusloos te zijn. Dat wil zeggen, de API-client voor het verzoek zal de sessie voor u afhandelen in plaats van Rails.
⋮
Antwoord 4, autoriteit 12%
Sinds de rails 5 kunt u ook een nieuwe klasse maken met :: api In plaats van :: base:
class ApiController < ActionController::API
end
5, Autoriteit 2%
Als u de monsteractie van de monstercontroller
wilt uitsluiten
class TestController < ApplicationController
protect_from_forgery except: :sample
def sample
render json: @hogehoge
end
end
U kunt zonder problemen verzoeken van buitenaf verwerken.
6
Als u alleen CSRF-bescherming wilt overslaan voor een of meer controlleracties (in plaats van de volledige controller), probeer dit dan
skip_before_action :verify_authenticity_token, only [:webhook, :index, :create]
Waar [:webhook, :index, :create]
Sla de cheque over voor die 3 acties, maar u kunt veranderen in welke u
wilt overslaan
7
De eenvoudigste oplossing voor het probleem is om standaard dingen in je controller te doen of je kunt het direct in ApplicationController
zetten:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, prepend: true
end