Ruby on Rails3で、Flashから何らかのデータをPOSTしようとすると、次のように怒られる。
WARNING: Can't verify CSRF token authenticity
これは、Railsでフォームを使うとCSRF対策にトークンが自動生成されるんだけど、そのトークンが送られてないよ!と怒っている。GETメソッド以外はCSRFトークンが必須となっているようだ。CSRF対策を無効にして回避することも出来るのだけれど、さすがにそれはしたくない。と言う事で、FlashにCSRFトークンを渡し、FlashからPOSTする際にそのトークンを渡すようにする。ついでにセッションIDも同じように渡し、POSTする際にセッションが有効になるようにす
今回想定するアプリは次のようなモノだ。
1. Rails上で作成したWebページにFlashアプリを埋め込む。
2. Flashアプリ上でデータを入力し、アップロードボタンを押すとPOSTでデータをアップロードする。
3. Railsでデータを受け取る。
何も考えずに作成すると、3でデータを受け取る際に、前述のエラーがでてしまう。
まずはFlashアプリへCSRFトークンとセッションIDを渡す。Flashアプリへ情報を渡すには、FlashVars属性を使う。CSRFトークンは<%= u(form_authenticity_token) %>で、セッションIDは<%= u(request.session_options[:id]) %>で書き出すことが出来る。注意するのは、FlashVarsにはURLエンコードが必要なので、u()でエンコードしている点だ。
<EMBED src="/swf/hoge.swf" FlashVars="token=<%= u(form_authenticity_token) %>&session=<%= u(request.session_options[:id]) %>" TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer"> </EMBED>
Flashからデータをポストするには次のような感じにする。CSRFトークンはauthenticity_tokenと言う名前、セッションIDはsession_idと言う名前で送信する。
var params:Object = loaderInfo.parameters; var token:String = params["token"]; var sessionId:String = params["session"]; var variables:URLVariables = new URLVariables(); variables.data = "何らかのデータ"; variables.authenticity_token = token; variables.session_id = sessionId; var urlRequest:URLRequest = new URLRequest(); urlRequest.url = "http://localhost:3000/upload"; urlRequest.method = URLRequestMethod.POST; urlRequest.data = variables; var postLoader:URLLoader = new URLLoader(); postLoader.load(urlRequest);
これでFlashからデータをPOSTして、なおかつセッションが有効になるよ!
No Comments