2012-06-24 5 views
18

サーバーとapiを消費するクライアントが別のドメインに属しているので、CORSを使用したいと考えています。そうするために、私は、サーバーの応答に対応するHTTPヘッダーを設定する必要があります。ユーザーが承認していない場合にDeviseでCORSヘッダーを送信する方法(401応答)

def cors_set_access_control_headers 
    headers['Access-Control-Allow-Origin'] = 'http://localhost' 
    headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS' 
    headers['Access-Control-Allow-Headers'] = '*, X-Requested-With, X-Prototype-Version, X-CSRF-Token, Content-Type' 
    headers['Access-Control-Max-Age'] = "1728000" 
end 

この方法はApplicationControllerbefore_filterとして使用されています。

一部のリソースでは、ユーザーを認証して認証する必要があります。リクエストはXHR/Ajax経由で行われます。したがって、ユーザーが認証されていない場合、Deviseは、サインインページにリダイレクトするのではなく、クライアントに401応答を送信します。しかし、CORSヘッダーを設定するフィルターはその応答には使用されません。したがって、401応答はクライアントに送信されません。クライアントで401応答を捕捉して使用したいと思います。

現在、私は工夫の認証方法を使用していないことで回避策を使用しますが、カスタム認証抜粋しています:

def authenticate_cors_user 
    if request.xhr? && !user_signed_in? 
    error = { :error => "You must be logged in." } 
    render params[:format].to_sym => error, :status => 401 
    end 
end 

これはあまりにもApplicationControllerbefore_filter、として設定されています。この方法でCORSヘッダーを設定するフィルターが起動され、すべて正常に動作します。

私はDeviseのデフォルトの動作を使用したいと思いますが、CORSヘッダーは401応答で設定する必要があります。これを行う方法?それにはwardenを設定する必要がありますか?

私自身の応答を作成する代わりに、Deviseによって生成された401応答に対してCORSヘッダーを設定するにはどうすればよいですか?

+0

それでも私はそのためのソリューションを持っていない:CORSハンドラが監視員の前にあるように、ミドルウェアの順序を指定します。もっと文脈を与えるために、私がこれをどのように使っているかについて私のブログ記事をチェックしてください:http://nils-blum-oeste.net/cors-api-with-oauth2-authentication-using-rails-and-angularjs –

答えて

21

私は正常ラックCORSの宝石https://github.com/cyu/rack-corsを使用してmy blogに私の経験を概説。

パンチライン:

config.middleware.insert_before Warden::Manager, Rack::Cors 
+0

あなたのアプローチはすばらしい、ありがとう!しかし、奇妙なことに、 'Devise'と' rack-cors'を連携させるためには、コードの行を1行だけ変更しなければならないことに変わりはありませんでした。 –

+0

ねえ、@ digger69。あなたは他の例外に問題がありましたか?例えば、私のアクション 'def index;で例外をスローした場合。エラーを起こす。 end' - RailsはCORSヘッダー(rack-cors)を返しません。それはあなたのために働くのですか? –

+4

PS: 'config.middleware.insert 0、Rack :: Cors'を使って、他の可能なミドルウェアの前に' Rack :: Cors'が挿入されるようにすることもできます。 –

0

一般に、CORSヘッダーは嫌です。リダイレクトにはHAProxyを使用することをお勧めします。

HAProxyを使用すると、website/api /にアクセスするすべてのリクエストを内部的にレールマシンにリダイレクトするように設定できます。

frontend main *:80 
    acl api  path_beg -i /api 
    acl app  path_beg -i /app 
backend app_backend 
    reqrep ^([^\ ]*)\ /app/(.*) \1\ /\2 
    balance roundrobin 
    server app_files smartphoneapp.localhost:8000 
backend api_backend 
    reqrep ^([^\ ]*)\ /api/(.*) \1\ /\2 
    balance roundrobin 
    server app_api localhost:3000 
+0

CORSはプロキシを使用して回避する必要があります。しかし、それでもDevise/wardenとうまく対処する方法がなければなりません。 –

+0

この記事をご覧ください: http://www.tsheffler.com/blog/?p=428 – Hendrik

関連する問題