Je veux faire POST request
à mon dev local, comme ceci:
HTTParty.post('http://localhost:3000/fetch_heroku',
:body => {:type => 'product'},)
Cependant, à partir de la console du serveur, il indique
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
Voici mon contrôleur et la configuration des routes, c'est assez simple.
def fetch_heroku
if params[:type] == 'product'
flash[:alert] = 'Fetch Product From Heroku'
Heroku.get_product
end
end
post 'fetch_heroku' => 'admin#fetch_heroku'
Je ne suis pas sûr de ce que je dois faire? Désactiver le CSRF fonctionnerait certainement, mais je pense que cela devrait être mon erreur lors de la création d'une telle API.
Y at-il une autre configuration que je dois faire?
La falsification des références entre sites survient lorsqu'une page Web malveillante incite les utilisateurs à exécuter une requête qui n'est pas destinée, par exemple, à l'aide de bookmarklets, d'iframes ou simplement en créant une page qui est visuellement assez similaire pour duper les utilisateurs.
La protection CSRF de Rails est conçue pour les applications Web "classiques". Elle garantit simplement que la demande provient de votre propre application Web. Un jeton CSRF fonctionne comme un secret que seul votre serveur connaît: Rails génère un jeton aléatoire et le stocke dans la session. Vos formulaires envoient le jeton via une entrée masquée et Rails vérifie que toute demande non GET inclut un jeton qui correspond à ce qui est stocké dans la session.
Cependant, une API est généralement, par définition, multisite et doit être utilisée dans davantage que votre application Web, ce qui signifie que le concept de CSRF n’est pas tout à fait applicable.
Au lieu de cela, vous devez utiliser une stratégie basée sur un jeton consistant à authentifier les demandes d'API avec une clé d'API et un secret puisque vous vérifiez que la demande provient d'un client d'API approuvé - et non de votre propre application.
Vous pouvez désactiver CSRF comme indiqué par @dcestari:
class ApiController < ActionController::Base
protect_from_forgery with: :null_session
end
Mis à jour. Dans Rails 5, vous pouvez générer des applications utilisant uniquement l'API à l'aide de l'option --api
:
Rails new appname --api
Ils n'incluent pas le middleware CSRF et de nombreux autres composants qui sont superflouus.
Un autre moyen de désactiver CSRF sans rendre de session nulle consiste à ajouter:
skip_before_action :verify_authenticity_token
dans votre contrôleur Rails. Cela garantira que vous aurez toujours accès aux informations de session.
Encore une fois, veillez à ne le faire que dans les contrôleurs d'API ou dans d'autres endroits où la protection CSRF ne s'applique pas tout à fait.
Il existe des informations pertinentes sur une configuration de CSRF en ce qui concerne les contrôleurs API sur api.rubyonrails.org :
⋮
Il est important de noter que les requêtes XML ou JSON sont également affectées. Si vous créez un API , vous devez modifier la méthode de protection contre la falsification dans
ApplicationController
(par défaut::exception
):class ApplicationController < ActionController::Base protect_from_forgery unless: -> { request.format.json? } end
Nous souhaitons peut-être désactiver la protection CSRF pour les API car elles sont généralement conçues pour être sans état. En d’autres termes, la requête API client gérera la session pour vous au lieu de Rails.
⋮
Dans Rails 5, vous pouvez également créer une nouvelle classe avec :: API au lieu de :: Base:
class ApiController < ActionController::API
end
Si vous souhaitez exclure l'exemple d'action du contrôleur
class TestController < ApplicationController
protect_from_forgery :except => [:sample]
def sample
render json: @hogehoge
end
end
Vous pouvez traiter les demandes de l'extérieur sans aucun problème.