web-dev-qa-db-ja.com

Rails 4 Authenticity Token

真正性トークンの問題に遭遇したとき、新しいRails 4アプリ(Ruby 2.0.0-p0)で作業していました。

respond_toクラスメソッドを使用して)jsonに応答するコントローラーを作成しているときに、createを使用してレコードを作成しようとしたときに、ActionController::InvalidAuthenticityToken例外を取得し始めたcurlアクションに到達しました。

-H "Content-Type: application/json"を設定し、-d "<my data here>"でデータを設定したことを確認しましたが、それでも運はありません。

Rails 3.2(Ruby 1.9.3)を使用して同じコントローラーを作成しようとしましたが、認証トークンの問題はまったくありませんでした。私は周りを検索しましたが、Rails 4.の認証トークンにいくつかの変更があることがわかりました。私が理解したところから、それらはもはやフォームに自動的に挿入されません。これは何らかの形で非HTMLコンテンツタイプに影響していると思われます。

HTMLフォームをリクエストし、認証トークンを取得してから、そのトークンで別のリクエストを行うことなく、これを回避する方法はありますか?または、私は完全に明らかな何かを完全に見逃していますか?

編集:新しいRails 4アプリで、何も変更せずにscaffoldを使用して新しいレコードを作成しようとしましたが、同じ問題にぶつかりました。した。

197
alexcoco

私はちょうどそれを考え出したと思います。 (新しい)デフォルトを変更しました

protect_from_forgery with: :exception

protect_from_forgery with: :null_session

ApplicationControllerのコメントに従って。

# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.

request_forgery_protecton.rbのソース、またはより具体的には次の行を見ると違いがわかります。

In Rails 3.2

# This is the method that defines the application behavior when a request is found to be unverified.
# By default, \Rails resets the session when it finds an unverified request.
def handle_unverified_request
  reset_session
end

In Rails 4

def handle_unverified_request
  forgery_protection_strategy.new(self).handle_unverified_request
end

これは 以下 と呼ばれます:

def handle_unverified_request
  raise ActionController::InvalidAuthenticityToken
end
273
alexcoco

Csrf保護をオフにする代わりに、次のコード行をフォームに追加することをお勧めします。

<%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %> 

もしあなたがformを生成するためにform_forやform_tagを使っているなら、それは自動的にフォームに上記のコード行を追加します。

71
xiaoboa

次の行をフォームに追加するとうまくいきました。

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
70
Carlos

APIを排他的に実装していない限り、一般的にCSRF保護を無効にするのは良いとは思いません。

Rails 4 APIのドキュメントで ActionController を見ると、コントローラごとまたはメソッドごとに偽造防止を無効にできることがわかりました。

例えば、あなたが使うことができるメソッドのためにCSRF保護をオフにするために

class FooController < ApplicationController
  protect_from_forgery except: :index
32
roamingthings

同じ問題に遭遇しました。私のコントローラに追加することでそれを修正しました:

      skip_before_filter :verify_authenticity_token, if: :json_request?
8
user1756254

試しましたか?

 protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format.json? }
7
zechtz

この公式ドキュメント - apiの偽造防止を適切に無効にする方法について説明します http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html

4
konung

これはRailsのセキュリティ機能です。このコード行を次の形式で追加してください。

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

ドキュメントはここにあります: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html

3
B Liu

これらの機能は、セキュリティと偽造防止の目的で追加されました。
しかし、あなたの質問に答えるために、ここにいくつかの入力があります。コントローラ名の後にこれらの行を追加することができます。

そのようです、

class NameController < ApplicationController
    skip_before_action :verify_authenticity_token

これはRailsのさまざまなバージョン用の行です。

Rails

skip_before_filter:verify_authenticity_token

Rails 4

skip_before_action:verify_authenticity_token


すべてのコントローラルーチンに対してこのセキュリティ機能を無効にする場合は、application_controller.rbファイルでprotect_from_forgeryの値を:null_sessionに変更できます。

そのようです、

class ApplicationController < ActionController::Base
  protect_from_forgery with: :null_session
end
2
Kent Aguilar

Formタグにauthenticity_token: trueを追加してください

1
Salma Gomaa

RailsでjQueryを使用している場合は、信憑性トークンを検証せずにメソッドへの入力を許可することには注意してください。

jquery-ujsがあなたのためにトークンを管理できます

あなたはすでにjquery-Rails gemの一部としてそれを持っているべきですが、application.jsにそれを含める必要があるかもしれません。

//= require jquery_ujs

これで、必要なことはすべて完了しました。これで、Ajax呼び出しは機能するはずです。

詳細については、以下を参照してください。 https://github.com/Rails/jquery-ujs

1
user1555400

私のテストはすべてうまくいきました。しかし、何らかの理由で環境変数をテストしないように設定しました。

export Rails_ENV=something_non_test

私はActionController::InvalidAuthenticityToken例外を受け始めたので、この変数の設定を解除するのを忘れました。

$Rails_ENVの設定を解除した後、私のテストは再び働き始めました。

0
mridula

あなたがあなた自身のhtmlフォームを定義するとき、あなたは認証トークン文字列を含まなければなりません、それはセキュリティ上の理由からコントローラに送られるべきです。信憑性トークンを生成するためにRailsフォームヘルパーを使用する場合は、次のようにformに追加されます。

<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>

そのため、この問題の解決策は、セキュリティを犠牲にするのではなく、authenticicity_tokenフィールドを追加するか、Railsのフォームヘルパーを使用することです。

0
amjad