ActionController :: InvalidAuthenticityToken


148

以下は、私のRailsアプリケーションのフォームが原因のエラーです。

Processing UsersController#update (for **ip** at 2010-07-29 10:52:27) [PUT]
  Parameters: {"commit"=>"Update", "action"=>"update", "_method"=>"put", "authenticity_token"=>"ysiDvO5s7qhJQrnlSR2+f8jF1gxdB7T9I2ydxpRlSSk=", **more parameters**}

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

これはすべての非getリクエストで発生し、ご覧のauthenticity_tokenとおりです。

回答:


207

同じ問題がありましたが、ページキャッシュされたページがありました。ページは、古い認証トークンと、post / put / deleteメソッドを使用してすべてのアクションでバッファリングされ、偽造の試みとして認識されます。エラー(422 Unprocessable Entity)がユーザーに返されました。

Rails 3のソリューション:
追加:

 skip_before_filter :verify_authenticity_token  

または、「sagivo」がRails 4で指摘したように、以下を追加します。

 skip_before_action :verify_authenticity_token

キャッシュを行うページ。

@toobulkehとして、これは上の脆弱性ではありませんコメントし:index:showアクションが、上でこれを使用して注意してください:put:postアクション。

例えば:

 caches_page :index, :show  
 skip_before_filter :verify_authenticity_token, :only => [:index, :show]

リファレンス:http : //api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

skip_before_actionの賛成でbarlop-のRails 4.2は非推奨skip_before_filterによって追加注https://guides.rubyonrails.org/4_2_release_notes.html「メソッドの* _filterファミリは、ドキュメントから削除されました。彼らの使用は* _actionの賛成で推奨されメソッドのファミリー」

レール6あなたが使用することができます(「collimarcoは」指摘したように)skip_forgery_protection、セッションデータを使用していないのREST APIのためにそれを使用しても安全であること。


3
おそらくそうではありません。投稿前にcaches_pageを知りませんでした。しかし、私はcaches_pageをチェックアウトします、ありがとう。
Nikita Rybak 2010

7
レール4skip_before_action :verify_authenticity_token
Sagiv Ofek 2014

88
これは脆弱性ではないですか?
クォンタムポテト2014年

6
これは:index, :showアクションの脆弱性ではありません。しかし、これを:put, :post行動に移すことに注意してください!
toobulkeh

14
これが必要になるケースがあるかもしれませんが(たとえば、ライフタイムに1回など)、セキュリティを無効にすることによってセキュリティを修正していることを認識する必要があります。非推奨
同等8 8

77

私にとって、Rails 4でのこの問題の原因は不明でした。

<%= csrf_meta_tags %>

メインアプリケーションレイアウトの行。レイアウトを書き直したときに誤って削除してしまいました。

これがメインレイアウトにない場合は、CSRFトークンを有効にするすべてのページで必要になります。


2
このエラーも発生しています。しかし、それは中断されます。これが理由であるか、またはこれがエラーのあるすべてのリクエストに影響しないか?
Ryan-Neal Mes、2015年

@ Ryan-NealMes、テンプレートにその行がない場合、エラーが発生します。そのため、一部のテンプレートにはそれがあり、他のテンプレートにはない可能性があります。
James McMahon

1
@JamesMcMahonのおかげで、私のケースは実際にはユーザーがCookieをクリアしたか、Cookieをブロックしたことが原因であるとわかりました。この質問から負荷を学んだ!
Ryan-Neal Mes、2015年

61

このエラーにはいくつかの原因があります(Rails 4に関連)。

1. <%= csrf_meta_tags %>ページレイアウトに存在することを確認します

。2. オプションform_for付きのヘルパーを使用している場合は、AJAX呼び出しで認証トークンが送信されていることを確認します 。remote: trueそうでない場合は<%= hidden_field_tag :authenticity_token, form_authenticity_token %>、フォームブロックに行を含めることができます。

3.リクエストがキャッシュされたページから送信されている場合は、フラグメントキャッシュを使用して、リクエストを送信するページの一部などを除外しますbutton_to。そうでない場合、トークンは古くなったり無効になります。

私はcsrf保護を無効にするのをためらいます...


csrf_meta_tagsは<head>内にある必要がありますか?ターボリンクと競合しないことをどのように確認できますか?
輝き

37

authenticity_tokeninフォームを追加するだけで修正されました。

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

3
Railsはデフォルトでトークンを送信することになっています。明示的に指定する必要はありません。この状況ではトークンがどういうわけかここで変更されたように感じます。
Abhi 2017

1
ただし、ヘルパーを使用しないフォームを作成した場合は、手動で配置する必要があります。
アンドレ・ギマランイス酒田

30

認証トークンは、リクエストがサイトのフォームからではなく他の場所から送信されたことを証明するためにビューで生成されるランダムな値です。これにより、CSRF攻撃から保護されます。

http://en.wikipedia.org/wiki/Cross-site_request_forgery

そのクライアント/ IPが誰であるかを確認します。ビューをロードせずにサイトを使用しているようです。

さらにデバッグする必要がある場合は、この質問から始めるのが適切です。RailsAuthenticityトークンについて

説明のために編集:これは、フォームをWebサイトにレンダリングせずに、フォーム送信を処理するアクションを呼び出していることを意味します。これは悪意がある(スパムコメントを投稿するなど)か、顧客がWebサービスAPIを直接使用しようとしていることを示している可能性があります。あなたはあなたの製品の性質とあなたの要求を分析することによってそれに答えることができる唯一の人です。


1
ありがとうございます。ただし、認証トークンが何であるかはすでに知っています。そのクライアント/ IPが誰であるかを確認します。ビューをロードせずにサイトを使用しているようです。「ビューをロードしない」とはどういう意味ですか?
Nikita Rybak 2010

1
つまり、誰か(おそらくスパマー)が、アプリケーションのユーザーインターフェイスを経由せずにフォームにデータを送信している可能性があります。たとえば、curlなどのコマンドラインプログラムを使用してこれを行うことができます。
John Topley、2010

ジョンはそのとおりです。それは彼らがあなたのウェブサイトにあなたのフォームをレンダリングすることなくあなたのフォーム送信を処理するアクションを呼び出していることを意味します。これは悪意がある(スパムコメントを投稿するなど)か、顧客がWebサービスAPIを直接使用しようとしていることを示している可能性があります。あなたはあなたの製品の性質とあなたの要求を分析することによってそれに答えることができる唯一の人です。
Winfield、

わかりました、Winfieldのコメントを誤解しました。ブラウザーを使用するときに、アプリがなんらかの理由で「ビューをロードする」ように構成されていないと思いました。
Nikita Rybak 2010

1
別の考えもありました。これらのリクエストにはトークンが含まれていますが、それは有効ではありません。これは、フォームをレンダリングするページをキャッシュするか、フォームの古いバージョンを引き起こす可能性のある何かをキャッシュすることによって引き起こされる可能性があります。
Winfield

26

ActionController::InvalidAuthenticityTokenまた、誤って設定されたリバースプロキシが原因である可能性もあります。これは、スタックトレースで次のような行が表示される場合ですRequest origin does not match request base_url

HTTPSリクエストのレシーバーとしてリバースプロキシ(nginxなど)を使用し、暗号化されていないリクエストをバックエンド(Railsアプリなど)に送信する場合、バックエンド(より具体的には、Rack)は、元のクライアントリクエストに関する詳細情報を含むヘッダーを期待しますさまざまな処理タスクとセキュリティ対策を適用できるようにするため。

詳細については、https//github.com/rails/rails/issues/22965を参照してください

TL; DR:解決策はいくつかのヘッダーを追加することです:

upstream myapp {
  server              unix:///path/to/puma.sock;
}

location / {
  proxy_pass        http://myapp;
  proxy_set_header  Host $host;
  proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header  X-Forwarded-Proto $scheme;
  proxy_set_header  X-Forwarded-Ssl on; # Optional
  proxy_set_header  X-Forwarded-Port $server_port;
  proxy_set_header  X-Forwarded-Host $host;
}

うわー、私はこの問題の解決策を3時間探していました。
evexoio 2018

レール側でこれを解決しようとする6時間ありがとう
Joe Half Face

18

回答するには遅すぎますが、解決策を見つけました。

独自のhtmlフォームを定義すると、セキュリティ上の理由からコントローラーに送信する必要がある認証トークン文字列が失われます。しかし、レールフォームヘルパーを使用してフォームを生成すると、次のようなものが得られます

<form accept-charset="UTF-8" action="/login/signin" method="post">
  <div style="display:none">
    <input name="utf8" type="hidden" value="&#x2713;">
    <input name="authenticity_token" type="hidden" 
      value="x37DrAAwyIIb7s+w2+AdoCR8cAJIpQhIetKRrPgG5VA=">
    .
    .
    .
  </div>
</form>

したがって、問題の解決策は、authenticity_tokenフィールドを追加するか、レールを削除、ダウングレード、またはアップグレードするのではなく、ヘルパーフォームヘルパーを使用することです。


9

あなたが行っている場合rake rails:update、あるいは、最近あなたを変えconfig/initializers/session_store.rb、これはブラウザの古いクッキーの症状かもしれません。うまくいけば、これはdev / testで行われ(それは私用でした)、問題のドメインに関連するすべてのブラウザーCookieをクリアできます。

これが本番key環境であり、を変更した場合は、古いCookieを使用するように変更することを検討してください(<-推測のみ)。


はい!私にとっては、空のsession_store.rbがエラーの原因でした。
lafeber

6

JavaScript呼び出しでこの問題が発生しました。私はapplication.jsファイルにjquery_ujsを要求するだけでそれを修正しました。


はい、そうです。この問題もあり、アプリケーションjsにjquery_ujsを追加しました。出来た。
Abhi 2017

3

私たちは同じ問題を抱えていましたが、これはhttp://を使用するリクエストのみであり、https://を使用するリクエストではないことに気付きました。原因はsecure: truesession_store でした:

Rails.application.config.session_store(
  :cookie_store,
  key: '_foo_session',
  domain: '.example.com',
  secure: true
)

HTTPS〜everywhereを使用して修正:)


rails s開発用にセットアップしたSSLエンドポイントの代わりに(非SSL)を使用すると、この問題が発生しました。私がやっていることに気づいたのは、あなたのコメントを読んでからでした。SSLを使用するように切り替えると、物事は再び機能し始めました。ありがとう!
Karl Wilbur

1
私は開発中にこの問題に直面しました。代わりにsecure: true私が書いたsecure: !Rails.env.development?
murb

1

レール5のprotect_from_forgery prepend: true場合、スキップするよりも追加する方が良い verify_authentication_token


5
どうして?参照を追加できますか?
kwerle


0

この問題が発生したのは、コントローラーをアプリにコピーして貼り付けたためです。に変更ApplicationControllerする必要がありましたApplicationController::Base


0

localhostでも同じ問題が発生しました。アプリのドメインを変更しましたが、URLとホストファイルにまだ古いドメインがありました。新しいドメインを使用するようにブラウザーのブックマークとホストファイルを更新しましたが、すべて正常に動作します。


0

たぶん、あなたはNGINXをHTTPS用に設定していますが、証明書は無効ですか?私は過去に同様の問題があり、httpからhttpsにリダイレクトすると問題が解決しました


0

<%= csrf_meta_tags%>が存在し、ブラウザでのCookieのクリアが機能していることを確認しました。


0

アプリケーションの読み込みを高速化するためのChrome Lighthouseの推奨事項に従って、Javascriptを非同期にしました。

views/layout/application.html.erb

<%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload', async: true %>

これはすべてを壊し、私のリモートフォームのトークンエラーを受け取りました。削除async: trueすると問題が修正されました。


0

この回答はRuby on Railsに固有のものですが、うまくいけば誰かの役に立つでしょう。

すべての非GETリクエストにCSRFトークンを含める必要があります。JQueryを使用することに慣れている場合、Railsはjquery-ujsその上に構築され、いくつかの非表示機能を追加する、というヘルパーライブラリを持っています。それが行うことの1つは、すべてのajax要求にCSRFトークンを自動的に含めることです。こちらをご覧ください

私のようにそれから切り替えると、エラーが発生する可能性があります。トークンを手動で送信するか、別のライブラリを使用してDOMからトークンを取得することができます。詳細については、この投稿を参照してください。


-1

Rails 5では、2行のコードを追加する必要があります

    skip_before_action :verify_authenticity_token
    protect_from_forgery prepend: true, with: :exception

-2

取り付け

gem 'remotipart' 

助けられる


3
これは答えかもしれませんが、答えの本質的な部分を含め、それがなぜ/どのように機能するかを説明することも役立ちます。
ロイ・リー、

-15

2.3.8から2.3.5にダウングレードすることで問題が解決しました。(悪名高い「あなたはリダイレクトされています。」問題と同様に)


@Flip多分それは受け入れられた答えを更新するアイデアですか?
lafeber
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.