2.0ã®cookie session storeã使ãã
Rails2.0ã®å¤æ´ç¹ã§ãã»ãã·ã§ã³(session)ãã¼ã¿ã®ä¿åå ãã¯ããã¼(cookie)ã«ãªã£ãã¨ãããã¨ããããç®ã«ããã確èªãã¦ã¿ãã¨ã確ãã«ä»¥åã¯tmp/sessionsãã©ã«ãã®ä¸ã«å¸¸ã«ã»ãã·ã§ã³ãã¡ã¤ã«ããããå¢ãç¶ãã¦ãããã2.0ç°å¢ã«ãã¦ããã¯ãã¤ã空ã£ã½ã ããããªãã¨ãæ¬å½ã«ã¯ããã¼ã«ä¿åããã¦ããã®ãï¼ã©ã®ããã«ä¿åããã¦ããã®ãï¼å®éã«è¦ãã¦ã¿ãããªã£ã...ã
ã¯ããã¼ã確èªãã
- MacOS Xçã®Firefox2.0ã®ã¯ããã¼ã¯ãFirefoxã®ç°å¢è¨å® >> ãã©ã¤ãã·ã¼ ã¿ã >> Cookieã表示 ãã¿ã³ãã§è¡¨ç¤ºãããã
- æ³å以ä¸ã®ã¯ããã¼ã®å¤ãã«é©ããä¸ã¤ãã¤è¦ã¦ãã¦ã¯ããªãç¡ãã®ã§ãæ¤ç´¢ã§ãlocalhastãã¨å ¥åãã¦ã¿ãã
- ããã¨ä¸æ°ã«çµãè¾¼ã¾ããCookieåããã_test_slip202_sessionããæ±ããã¯ããã¼ã ã¨äºæ³ã§ããã
- ã_ããã¸ã§ã¯ãå_sessionãã®æ¸å¼ã«ãªã£ã¦ããããã ã
- ããã¯ã¤ã¾ããconfig/environment.rbã®ä»¥ä¸ã®è¨è¿°ã¨ä¸è´ãã¦ããã®ã ã
...ï¼ä¸ç¥ï¼... Rails::Initializer.run do |config| ...ï¼ä¸ç¥ï¼... config.action_controller.session = { :session_key => '_test_slip202_session', :secret => '9384c0b735c5d5ff1aafbef9bab1f9b538ef33b0dbade61707d86a0e53ed0a79e649567288ccd877767939d377a512f294a120ac9968ceec49697c6e5e6d2363' } ...ï¼ä¸ç¥ï¼...
- ã¯ãªãã¯ããã¨ãä¸ã®æ¹ã«ä»¥ä¸ã®å 容ã表示ãããã
åå | _test_slip202_session |
å 容 | BAh7BzoMY3NyZl9pZCIlYmE0MjAyNzRkYTczNjg0NGI5YmM5MzBlYWQzMTcw%250AMzMiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%250Ac2h7AAY6CkB1c2VkewA%253D--1169bd07e96689065f9af999e6b9866351f14c57 |
ãã¹ã | localhost |
ãã¹ | / |
éä¿¡å¶é | æå·åã®æç¡ã«ããã常ã«éä¿¡ |
æå¹æé | ã»ãã·ã§ã³çµäºæ |
ã¯ããã¼ã復å ãã
ã¯ããã¼ãè¦ããã¨ã¯åºæ¥ãããæå³ã®åãããªãè±æ°åã®ç¾ åãè¦ã¦ãã¦ãããã¾ãã¡ãã³ã¨ããªããèªåãçè§£ã§ããå½¢ã§è¦ã¦ã¿ããã調ã¹ã¦ã¿ãã¨ãå å®¹ã®æååã®ã--ããå¢ã«ãã¦ã- å·¦å´ãã¨ã³ã³ã¼ãããããªãã¸ã§ã¯ããã¼ã¿
- å³å´ãã¯ããã¼ã®æ¹ãã鲿¢ã®ãããå·¦å´ã®ãã¼ã¿ã¼ãå ã«æå·åãããã§ãã¯ãã¼ã¿
ã¨ã³ã³ã¼ãã®æ¹æ³
ã¨ã³ã³ã¼ãã®æ¹æ³ãæ£ç¢ºã«ç¢ºèªãããããã½ã¼ã¹ã³ã¼ãã§èª¿ã¹ã¦ã¿ããèªåã®MacBook OSX10.5ç°å¢ã§ã¯ä»¥ä¸ã®ãã¡ã¤ã«ãæ±ããã½ã¼ã¹ã³ã¼ãã ã£ãã- /Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session/cookie_store.rb
- /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/session/cookie_store.rb
class CGI::Session::CookieStore ...ï¼ä¸ç¥ï¼... private # Marshal a session hash into safe cookie data. Include an integrity hash. def marshal(session) data = Base64.encode64(Marshal.dump(session)).chop CGI.escape "#{data}--#{generate_digest(data)}" end # Unmarshal cookie data to a hash and verify its integrity. def unmarshal(cookie) if cookie data, digest = CGI.unescape(cookie).split('--') unless digest == generate_digest(data) delete raise TamperedWithCookie end Marshal.load(Base64.decode64(data)) end end ...ï¼ä¸ç¥ï¼...ã¤ã¾ããã¨ã³ã³ã¼ãã»ãã³ã¼ãã®æ¹æ³ã¯ä»¥ä¸ã®ããã«ããã¹ãã¨åæã«è§£éããã
- ã¨ã³ã³ã¼ãã¯ãsessionãªãã¸ã§ã¯ã >> Marshal.dump >> Base64.encode64 >> CGI.escape
- ãã³ã¼ãã¯ãCGI.unescape >> Base64.decode64 >> Marshal.load >> sessionãªãã¸ã§ã¯ã
script/consoleã§è§£èªãã
test_slip202ããã¸ã§ã¯ãã®ãã£ã¬ã¯ããªã§ãscript/consoleãèµ·åãã¦ä»¥ä¸ã®ããã«ãã£ã¦ã¿ãã>> cookie = "BAh7BzoMY3NyZl9pZCIlYmE0MjAyNzRkYTczNjg0NGI5YmM5MzBlYWQzMTcw%250AMzMiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%250Ac2h7AAY6CkB1c2VkewA%253D--1169bd07e96689065f9af999e6b9866351f14c57"=> ["BAh7BzoMY3NyZl9pZCIlYmE0MjAyNzRkYTczNjg0NGI5YmM5MzBlYWQzMTcw%0AMzMiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7AAY6CkB1c2VkewA%3D", "1169bd07e96689065f9af999e6b9866351f14c57"]ããã...dump format errorãåºã¦æ¢ã¾ã£ã¦ãã¾ã...ãã¬ãã¯ãªã ãªããdump format errorãªã®ãæ©ãã§ããããä¸ã¤ä¸èªç¶ãªã¨ããã«æ°ä»ãããCGI.unescapeãã¦ããã¯ããªã®ã«ããã®å¾ã®dataæååã®ä¸ã«"%0A"ã"%3D"ãè¦ããã®ã ãã¨ã¹ã±ã¼ãæååã復å ãã¦ããã¯ããªã®ã«ãããã¯ãããã...ãCGI.unescapeåã®æååã確èªãã¦ã¿ãã¨ããã®ç®æã¯"%250A"ã¨"%253D"ã¨ãªã£ã¦ããã"%25"ãã¤ã¾ãã¢ã¹ãã¼ã³ã¼ã表ã®16鲿°æåã³ã¼ãã§ç¢ºèªããã¨ã%ãã ããããããCGI.escapeã2åå¦çãã¦ããå¯è½æ§ãããã ã¨ãããã¨ã§ãCGI.unescapeã2åå¦çããæé ã§ãã£ã¦ã¿ããArgumentError: dump format error(0x33) from (irb):109:in `load' from (irb):109>> cookie = "BAh7BzoMY3NyZl9pZCIlYmE0MjAyNzRkYTczNjg0NGI5YmM5MzBlYWQzMTcw%250AMzMiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%250Ac2h7AAY6CkB1c2VkewA%253D--1169bd07e96689065f9af999e6b9866351f14c57"
=> ["BAh7BzoMY3NyZl9pZCIlYmE0MjAyNzRkYTczNjg0NGI5YmM5MzBlYWQzMTcw%0AMzMiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7AAY6CkB1c2VkewA%3D", "1169bd07e96689065f9af999e6b9866351f14c57"]=> "BAh7BzoMY3NyZl9pZCIlYmE0MjAyNzRkYTczNjg0NGI5YmM5MzBlYWQzMTcw\nMzMiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh\nc2h7AAY6CkB1c2VkewA="=> {"flash"=>{}, :csrf_id=>"ba420274da736844b9bc930ead317033"}è§£èªã§ããï¼ï¼ãããªè¦å´ãããªãã¦ãã<%= session.inspect %>ããã¥ã¼ã®ã©ããã§å®è¡ããã°ãsessionãªãã¸ã§ã¯ãã®å 容ã¯ç¢ºèªã§ããã®ã§ãã...ãèªåã®æã§ãã©ã¦ã¶ã®ã¯ããã¼ãã復å ãããã¨ã«é åãæããã®ã§ãï¼ã¯ããã¼ã®ä¸èº«ã確èª
ã¤ã¾ããã¯ããã¼ã®ä¸èº«ã¯ã以ä¸ã®ããã·ã¥ãªãã¸ã§ã¯ãã¨ãããã¨ã ï¼{"flash"=>{}, :csrf_id=>"ba420274da736844b9bc930ead317033"}
- "flash"=>{}ã¯ã次ã®ã¢ã¯ã·ã§ã³ã¾ã§ä¿æãããã»ãã·ã§ã³ãã¼ã¿ãä¸è¨ã¯ç©ºã®ããã·ã¥ãã¤ã¾ãflashã®ä¸èº«ã¯ç©ºã£ã½ã
- :csrf_id=>"ba420274da736844b9bc930ead317033"ã¯ãCSRF対çã®ããã®authenticity_tokenãçæããããã®ãã¼ã
authenticity_tokenã¨ã¯ï¼
以前のPUT問題ã§èª¿ã¹ã¦ããæãrails2.0ã®form_forã¯ã以ä¸ã®ããã«å±éããããã¨ã確èªããã<%# ãã¥ã¼: app/views/slips/edit.rhtml %> <% form_for(@slip) do |f| %> <% end %> <%# ä¸è¨ã¯ä»¥ä¸ã®HTMLãçæããã%> <form action="/slips/11" class="edit_slip" id="edit_slip_11" method="post"> <div style="margin:0;padding:0"> <input name="_method" type="hidden" value="put" /> <input name="authenticity_token" type="hidden" value="bc70df10a269ed11ebcd411fbebf0b732908f40b" /> </div> </form>è¦ããªãinputãã©ã¼ã ã§ã:_method=>"put"ã¨åæã«ã:authenticity_token=>"bc70df10a269ed11ebcd411fbebf0b732908f40b"ãéä¿¡ãã¦ããã®ã ããã®:authenticity_tokenãçæããæã«ãã¯ããã¼å ã®:csrf_idãå©ç¨ããã¦ããããã ããªãauthenticity_tokenãéä¿¡ããã®ãï¼
ããã¯ãCSRFï¼ã¯ãã¹ãµã¤ããªã¯ã¨ã¹ããã©ã¼ã¸ã§ãªï¼ã¨ããæªæã®ãããã¼ã¸ã¸ã®å¯¾çããããCSRFã«ã¤ãã¦ã¯ãæ¤ç´¢ããã°è©³ããæ¸ããããã¼ã¸CSRFについて - willnetさんの日記ãè¦ã¦ããªãã»ã©ï¼ã¨æãã¹ãããªã :authenticity_tokenã«ãã£ã¦ãå¤é¨ã®ãã¼ã¸ããã®ä¸æ£ãªéä¿¡ãç¡å¹ã«ãã¦ããããã ãï¼æ£ãã:authenticity_tokenãä¸ç·ã«éä¿¡ãã¦ãããã©ã¼ã ãã¼ã¿ã®ã¿åãä»ããããã«ãªã£ã¦ãããå¤é¨ã®ãã¼ã¸ã¯æ£ãã:authenticity_tokenãç¥ããã¨ãåºæ¥ãªãã®ã§ãï¼protect_from_forgeryã«ã¤ãã¦
rails2.0ããApplicationControllerã¯ãããã©ã«ãã§ä»¥ä¸ã®ããã«ã³ã¼ãã£ã³ã°ããã¦ããã# Filters added to this controller apply to all controllers in the application. # Likewise, all the methods added will be available for all controllers. class ApplicationController < ActionController::Base helper :all # include all helpers, all the time # See ActionController::RequestForgeryProtection for details # Uncomment the :secret if you're not using the cookie session store protect_from_forgery # :secret => '62131e8be3a35fd28465e41d6cd97cf9' endprotect_from_forgeryã¨ããé¨åã以åããæ°ã«ãªã£ã¦ããããããã«ãã£ã¦authenticity_tokenã«ä¸æ£ãç¡ããããã§ãã¯ãã¦ããããã ã
- 試ãã«ãFirebugã§authenticity_tokenãæ¹ãããã¦éä¿¡ãã¿ã³ãæ¼ãã¦ã¿ãã¨ãActionController::InvalidAuthenticityTokenã¨ããã¨ã©ã¼ãçºçããã
- 次ã«ãéä¿¡ãã¿ã³ãæ¼ãåã®æ¹ãããã¼ã¸ã«æ»ã£ã¦ãprotect_from_forgeryãã³ã¡ã³ãã¢ã¦ããã¦ããåãããã«éä¿¡ãã¿ã³ãæ¼ãã¦ã¿ãã¨ãä»åº¦ã¯æ£å¸¸ã«æ´æ°ããã¦ãã¾ã£ãã
:secretãªãã·ã§ã³ã®ã³ã¡ã³ãã¢ã¦ããæ°ã«ãªã...ã
protect_from_forgeryã®å¾ã®:secret => '62131e8be3a35fd28465e41d6cd97cf9'ãã³ã¡ã³ãã¢ã¦ãããã¦ãã¦è¯ãã®ã ãããï¼ã¨ä¸å®ãæãã¦ããããã»ãã·ã§ã³ãã¯ããã¼ã«ä¿åããæ¹å¼(cookie session store)ãªãã³ã¡ã³ãã¢ã¦ãããç¶æ ã§åé¡ãªãããã ã:secretãnilãªãããã®ä»£ããã«ã¯ããã¼å ã®:csrf_idãå©ç¨ããããã¨èªåã§ã¯çè§£ãããï¼ã»ãã¥ãªãã£ã«é¢ãããã¨ãªã®ã§ã詳細ã¯èªåèªèº«ã§ç¢ºèªãããã¨ããå§ããã¾ããï¼
- /Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/request_forgery_protection.rb
åèãã¼ã¸
以ä¸ã®ãã¼ã¸ãããã¸ãåèã«ãªãã¾ãããç´ æ´ããããã¼ã¸ã«æè¬ã§ãï¼