Je veux faire POST request
à mon développeur local, comme ceci:
HTTParty.post('http://localhost:3000/fetch_heroku',
:body => {:type => 'product'},)
Cependant, à partir de la console du serveur, il signale
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 ma configuration de contrôleur et de 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 ce devrait être mon erreur lors de la création d'une telle API.
Dois-je faire une autre configuration?
ruby-on-rails
cqcn1991
la source
la source
protect_from_forgery with: :null_session
.Réponses:
La falsification de demande intersite (CSRF / XSRF) se produit lorsqu'une page Web malveillante incite les utilisateurs à exécuter une demande qui n'est pas destinée, par exemple en utilisant des bookmarklets, des iframes ou simplement en créant une page suffisamment similaire visuellement pour tromper les utilisateurs.
La protection Rails CSRF est conçue pour les applications Web "classiques" - elle donne simplement une certaine assurance 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 intersite et destinée à être utilisée dans plus que votre application Web, ce qui signifie que tout le concept de CSRF ne s'applique pas tout à fait.
Au lieu de cela, vous devez utiliser une stratégie basée sur des jetons pour authentifier les demandes d'API avec une clé API et un secret, car vous vérifiez que la demande provient d'un client 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 uniquement des applications API en utilisant l'
--api
option:rails new appname --api
Ils n'incluent pas le middleware CSRF et de nombreux autres composants qui sont superflouus.
la source
Une autre façon de désactiver CSRF qui ne rendra pas une session nulle consiste à ajouter:
skip_before_action :verify_authenticity_token
dans votre contrôleur Rails. Cela garantira que vous avez toujours accès aux informations de session.
Encore une fois, assurez-vous de 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.
la source
protect_from_forgery except: [:my_method_name]
?Il y a des informations pertinentes sur une configuration de CSRF par rapport aux contrôleurs d'API sur api.rubyonrails.org :
la source
protect_from_forgery
c'est toujours nécessaire pour les API et les sources qui disent que ce n'est pas le cas. Que faire si l'API est destinée à une application à page unique, qui utilise le cookie de session pour l'authentification de l'utilisateur?Depuis Rails 5, vous pouvez également créer une nouvelle classe avec :: API au lieu de :: Base:
class ApiController < ActionController::API end
la source
Si vous souhaitez exclure l'action d'échantillon du contrôleur d'échantillons
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.
la source
La solution la plus simple au problème est de faire des choses standard dans votre contrôleur ou vous pouvez directement le mettre dans ApplicationController
class ApplicationController < ActionController::Base protect_from_forgery with: :exception, prepend: true end
la source