1. ホーム
  2. ruby-on-rails

[解決済み】Rails: POSTリクエスト時にCSRFトークンの真偽を確認できない

2022-03-17 09:53:14

質問

を作りたいのですが 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を作成した時点で私のミスであるべきだと思います。

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

解決方法は?

クロスサイトリクエストフォージェリ(CSRF/XSRF)とは、悪意のあるウェブページが、ブックマークレットやiframeを使用したり、ユーザーを欺くために視覚的によく似たページを作成したりして、意図しないリクエストを実行するように仕向けることをいいます。

その RailsのCSRF対策 は古典的なWebアプリのために作られたもので、リクエストがあなた自身のWebアプリから発信されたことを単純に保証します。CSRFトークンは、サーバだけが知っている秘密のように機能します。Railsはランダムなトークンを生成してセッションに保存します。Railsはランダムなトークンを生成してセッションに保存します。フォームがトークンを隠し入力で送信すると、RailsはGET以外のリクエストにセッションに保存されたものと一致するトークンが含まれているかどうかを確認します。

しかし、APIは通常、定義上、クロスサイトであり、自分のウェブアプリ以外で使われることを意図しています。つまり、CSRFの概念全体が当てはまらないのです。

その代わりに、APIキーとシークレットを使ってAPIリクエストを認証するトークンベースの戦略を使うべきだ。なぜなら、リクエストが自分のアプリからではなく、承認されたAPIクライアントから来ることを検証しているからだ。

CSRFは@dcestariさんが指摘しているように無効化することができます。

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

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

rails new appname --api

CSRFミドルウェアやその他多くのコンポーネントが含まれていないため、superflouusとなっています。