/ / Rails:POSTリクエストを行うときにCSRFトークンの信頼性を検証できません-ruby-on-rails

Rails:POSTリクエスト時にCSRFトークンの信頼性を検証できない - ruby​​-on-rails

私は作りたい POST request 私の地元の開発者に、このように:

  HTTParty.post("http://localhost:3000/fetch_heroku",
:body => {:type => "product"},)

ただし、サーバーコンソールからはレポートされます

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

これが私のコントローラーとルートのセットアップです。とても簡単です。

  def fetch_heroku
if params[:type] == "product"
flash[:alert] = "Fetch Product From Heroku"
Heroku.get_product
end
end

post "fetch_heroku" => "admin#fetch_heroku"

何をする必要があるのか​​わかりません。CSRFをオフにすることは確かに機能しますが、そのようなAPIを作成するときは私の間違いだと思います。

他に必要な設定はありますか?

回答:

回答№1の53

クロスサイト参照偽造は、悪意のある場合ですWebページは、ブックマークレットやiframeを使用したり、ユーザーをだますのに十分な視覚的類似性のあるページを作成したりするなどして、意図しないリクエストを実行するようにユーザーを騙します。

RailsCSRF保護 「古典的な」ウェブアプリのために作られています-それは単にリクエストが独自のWebアプリから発信されたというある程度の保証を提供します。 CSRFトークンは、サーバーだけが知っている秘密のように機能します。Railsはランダムなトークンを生成し、それをセッションに保存します。フォームは非表示の入力を介してトークンを送信し、RailsはGET以外のリクエストにセッションに保存されているものと一致するトークンが含まれていることを確認します。

ただし、APIは通常、定義上クロスサイトであり、Webアプリ以外で使用することを目的としています。つまり、CSRFの概念全体が完全に適用されるわけではありません。

代わりに、トークンベースの戦略を使用する必要がありますリクエストが自分のアプリからではなく、承認されたAPIクライアントからのものであることを確認しているため、APIキーとシークレットを使用してAPIリクエストを認証します。

@dcestariで指摘されているように、CSRFを非アクティブ化できます。

class ApiController < ActionController::Base
protect_from_forgery with: :null_session
end

更新しました。 Rails 5では、を使用してAPIのみのアプリケーションを生成できます。 --api オプション:

rails new appname --api

これらには、CSRFミドルウェアやその他のすばらしいコンポーネントは含まれていません。


回答№2の場合は34

nullセッションをレンダリングしないCSRFをオフにする別の方法は、次を追加することです。

skip_before_action :verify_authenticity_token Railsコントローラーで。これにより、セッション情報に引き続きアクセスできるようになります。

繰り返しになりますが、これはAPIコントローラーまたはCSRF保護が完全に適用されない他の場所でのみ行うようにしてください。


回答№3の場合は3

上のAPIコントローラーに関するCSRFの構成に関する関連情報があります api.rubyonrails.org

XMLまたはJSONリクエストも影響を受けることを覚えておくことが重要です。 API で偽造保護方法を変更する必要があります ApplicationController (デフォルト: :exception):

class ApplicationController < ActionController::Base
protect_from_forgery unless: -> { request.format.json? }
end

APIは通常ステートレスになるように設計されているため、APIのCSRF保護を無効にすることをお勧めします。つまり、リクエスト API Railsの代わりにクライアントがセッションを処理します。