Rails4でFaceookアプリを作ってまして、facebookに埋め込む形でのアプリの設定をしても、白い画面が表示されるだけで思ったようにWebアプリの画面を表示されなかった。
原因はFacebookのキャンバスページではiframeを使用していて、Rails4側でその表示を拒否しているからだった。
どうやってiframeでの表示を拒否しているかというと、レスポンスのヘッダでX-Frame-Optionsというものを使用することによって実現していることが分かった。
X-Frame-Options レスポンスヘッダ – HTTP | MDN
X-Frame-Options HTTP レスポンスヘッダは、ブラウザがページを <frame> または <iframe> の内部に表示することを許可するかを示すことができます。
とはいえ、レスポンスヘッダに従うかどうかはブラウザの実装次第といったところか。メインマシンのMacBook AirにインストールしているFirefox、Chrome、SafariではちゃんとX-Frame-Optionsに従っていた。
Firebugでレスポンスヘッダを確認してみるとRails4アプリは次のようにX-Frame-OptionsヘッダでSAMEORIGIN
と返していた。これは同じ生成元からでないとiframeでの表示はできず、外部からは表示できないという設定でだ。
Rails3のアプリを確認してみたがX-Frame-Optionsヘッダは出力されてなかったのでRails4から出力されるようになったようだ。
HTTP/1.1 200 OK X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff x-ua-compatible: chrome=1
Ruby on Rails Security Guide
Rails Guidesにも記載されている。
Every HTTP response from your Rails application receives the following default security headers.
config.action_dispatch.default_headers = { 'X-Frame-Options' => 'SAMEORIGIN', 'X-XSS-Protection' => '1; mode=block', 'X-Content-Type-Options' => 'nosniff' }You can configure default headers in config/application.rb.
config.action_dispatch.default_headers = { 'Header-Name' => 'Header-Value', 'X-Frame-Options' => 'DENY' }
Rails Guidesではハッシュを書き換えるようになっているけど、X-Frame-Options
だけ変更できればよいので、次の様に記述してFacebookのアクセス元となるhttps://apps.facebook.com
を設定しておけばよい。
module Myapp class Application < Rails::Application config.action_dispatch.default_headers['X-Frame-Options'] = "Allow-From https://apps.facebook.com" end end
アプリを再起動してアクセスしてみるとレスポンスヘッダが変更できていることが確認できた。
これで、iframeからもアクセスできるようになった。
X-Frame-Options: Allow-From https://apps.facebook.com X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff x-ua-compatible: chrome=1
追記: 2013/12/19
そのときはこれでOKだったのだが、結局このURLだけでなくFacebookページと連携するためにhttps://www.facebook.com/
からもiframeで参照できる必要がでてきた。いまのところ、X-Frame-Options
で複数ドメインを設定する方法はみあたらず(まだ決まってない?)、このレスポンスヘッダは削除することにした。
config.action_dispatch.default_headers.delete('X-Frame-Options')
関連記事
- None Found