5

CORS を使用して別のドメインに認証する単一ページ アプリがあります。すべてのリクエストは JSON リクエストです。

私のアプリはOKを認証でき、GETリクエストをOKにすることができます。認証は token_authenticatable を使用しています。つまり、すべてのリクエストに「?auth_token=whatever」が追加されます

したがって、私の実際の問題は、PUT リクエストを実行しようとすると、CANCan ::AccessDenied (このページにアクセスする権限がありません。 )例外。

skip_before_filter :verify_authenticity_tokenRailsコントローラーに追加するだけで問題が解決します。

したがって、私の ajax リクエストが無効または空の csrf_token を送信しているとしか結論付けられません。

各ajaxリクエストでX-CSRF-Tokenヘッダーを正しく送信していると信じているため、それがどのようになるかはよくわかりません。

基本的に、私のアプリは認証され、Devise は auth_token と csrf_token を返します:

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

次に、これらのトークンを ajax アプリに保存しajaxSend、jQuery で使用してセットアップし、jQuery が各リクエストでこれらのトークンを渡すようにします。

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

次に、クロムネットワークタブで、GETリクエストごとにパラメーターとヘッダーauth_tokenが送信されていることを確認できます。X-CSRF-Token

ただし、PUT リクエストでは機能していないようです。

私の理論は、CORS が物事を詰め込んでいるというものです。CORS リクエストを行う場合、ブラウザは実際には最初に追加のOPTIONS リクエストを行い、このリソースにアクセスする権限があることを確認します。

X-CSRF-Tokenヘッダーを渡していないのはOPTIONSリクエストであると思われるため、レールはすぐにレール側のcsrf_tokenを無効にします。その後、jQuery が実際の PUT リクエストを行うと、渡された csrf_token は無効になります。

これが問題でしょうか?

それを証明するにはどうすればよいですか?問題のデバッグに役立つように、Chrome のネットワーク タブに OPTIONS リクエストが表示されないようです。

CSRFをオフにするだけなので、大きな問題ではありません。しかし、なぜそれが機能しないのか知りたいです。

4

3 に答える 3

1

OPTIONS リクエストを処理する必要があると思います。これは、CORS リクエストを許可するさまざまなヘッダーで応答する必要があります。IIRC は access-control-allow-method、access-control-allow-origin、access-control- です。許可ヘッダー。OPTIONS リクエストが失敗しているため、PUT リクエストが発生していない可能性があります。

于 2013-01-04T03:17:30.867 に答える
0

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

于 2012-10-24T05:38:06.247 に答える