2012-10-24 4 views
5

私はCORSを使用して別のドメインに認証を単一のページのアプリを持っています。すべてのリクエストはJSONリクエストです。「WARNING:CSRFトークン信憑性を検証できません」というエラーを - 工夫とCORSと:token_authenticatable

私のアプリがOKを認証することができますし、GET要求がOKにすることができます。認証はtoken_authenticatableを使用しています。私。 CSRFトークン信憑性を検証することはできませんレール内のメッセージログだけでなく、すべての要求が

だから、私の実際の問題は、私は私が 警告を取得PUTリクエストを実行しようとするときということである「?何auth_token =」を追加しますa CanCan :: AccessDenied(このページにアクセスする権限はありません)例外。

レールコントローラにskip_before_filter :verify_authenticity_tokenを単に追加するだけで問題が解決されます。

私は自分のajaxリクエストが無効または空のcsrf_tokenを送信していると判断できます。

各Ajaxリクエストで正しくX-CSRFトークンヘッダーを正しく送信していると思いますので、どうすればいいのか分かりません。そうjQueryのは、これらのトークンを渡し、それを設定し、私はその後、私のAJAXアプリでこれらのトークンを格納し、とjQueryでajaxSendを使用して

render :status => 200, :json => { 
    :auth_token => @user.authentication_token, 
    :csrf_token => form_authenticity_token 
} 

基本的に、私のアプリが認証と工夫がauth_tokenとcsrf_tokenを送り返し各要求に:

initialize: -> 
    @bindTo $(document), 'ajaxSend', @appendTokensToRequest 

appendTokensToRequest: (event, jqXHR, options) -> 
    if not @authToken? then return 

    if @csrfToken? 
    jqXHR.setRequestHeader 'X-CSRF-Token', @csrfToken 

    if options.type is 'POST' 
    options.data = options.data + (if options.data.match(/\=/) then '&' else '') + 
    $.param auth_token:@authToken 
    else 
    options.url = options.url + (if options.url.match(/\?/) then '&' else '?') + 
    $.param auth_token:@authToken 

Iは、次いで、それぞれについてそれがauth_token PARAMが送信される要求、ならびにX-CSRF-TokenヘッダをGET、クロムネットワークタブで見ることができます。それはしかし動作していないようですがPUT要求に

私の理論は、CORSは物事を詰めているということです。 CORSリクエストを行う場合、ブラウザは実際に追加の OPTIONSリクエストを作成し、まずこのリソースにアクセスする権限があるかどうかをチェックします。

私はそれがX-CSRFトークンヘッダーを渡さないOPTIONS要求であると考えます。したがって、レールはすぐにレールの終わりのcsrf_tokenを無効にします。 jQueryが実際のPUTリクエストを作成したときに渡されたcsrf_tokenはもはや有効ではありません。

これが問題になりますか?

私はそれを証明するために何ができますか? Chromeは問題をデバッグするのに役立つように、[ネットワーク]タブにOPTIONSリクエストを表示していないようです。

CSRFの機能を無効にすることができるので、大きな問題ではありません。しかし、なぜそれが動作していないのか知りたいです。 Railsでは

答えて

0

すべてのフォームの送信は、CSRFトークン信憑性を必要とします。 フォームを安全に送信するために使用します。 CSRFトークン(毎回)は、アプリケーションを開くときに新たに作成されます。 CSRFトークンがコントローラ内を通過していない場合、このWARNINGが表示されます。 すべてのフォーム提出でこのトークンを渡す必要があります。

+0

ええ、私はCSRFトークンを渡す必要があることを知っています。私はそれをX-CSRF-Tokenヘッダーの方法で渡していたと言いました。だから私はなぜ警告メッセージを受け取るのか分からない。私はそれがそのヘッダーを持っているように見えなかったOPTIONS要求と何かするかもしれないと思った。 – asgeo1

1

OPTIONS要求を処理する必要があると思います。これは、CORS要求を許可するさまざまなヘッダー、IIRCはアクセス制御許可メソッド、アクセス制御許可元、およびアクセス制御許可ヘッダー。 OPTIONS要求が失敗しているため、PUT要求はおそらく発生していません。

+0

Ok PUTリクエストが発生しているようです。私はとにかくこれを試してみるだろう。おそらくOPTIONSリクエストがトークンを無効にするでしょう、私はRailsについて個人的にはわかりません。しかし、おそらくOPTIONS応答は何らかの形で使われる新しいトークンを送ることができます。 – jamiebarrow

1

私はちょうど同じ問題に遭遇しました。問題はCORSで_session_idのCookieを送信できないことです。その結果、Railsがトークンの検証を試みると、session[:_csrf_token]nullとなり、Railsは比較の前に新しいものを生成します。

この問題を解決するには、CORSでCookie送信を有効にする必要があります。ここにはMozilla Developer Network referenceがあります。サーバーとクライアントの両方で作業を行う必要があります。

クライアント - お客様のクライアントテクノロジドキュメントを参照してください。

サーバ - プリフライト(HTTPのOPTIONS)呼び出しに応答してヘッダAccess-Control-Allow-Credentialstrueに(文字列)を設定します。

関連する問題