Jpmobileのtrans_sid
jpmobileのREADME
=== セッションIDの付与(Transit SID)
==== Cookie非対応携帯だけに付与する
class MyController
trans_sid
end
==== PCにも付与する
class MyController
trans_sid :always
end
PC向けのWebアプリをやってると縁がありませんが
cookieに対応していない携帯のブラウザ向けに
セッション管理をするためにURLとPOSTデータにセッションIDを引き回すことでセッション管理をする。
その機能をTransit SIDということで
jpmobile/lib/jpmobile/trans_sid.rb
module ActionController class CgiRequest alias_method :initialize_without_ext, :initialize def initialize(cgi, options = {}) initialize_without_ext(cgi, options) ENV['QUERY_STRING'] = query_string end end end class ActionController::Base #:nodoc: class_inheritable_accessor :trans_sid_mode alias :transit_sid_mode :trans_sid_mode class << self def trans_sid(mode=:mobile) include Jpmobile::TransSid self.trans_sid_mode = mode unless mode == :none # CSRF対策への対策 session :cookie_only => false # url/postからsession_keyを取得できるようhookを追加する unless ::CGI::Session.private_method_defined?(:initialize_without_session_key_fixation) ::CGI::Session.class_eval do alias_method :initialize_without_session_key_fixation, :initialize def initialize(cgi, options = {}) key = options['session_key'] if cgi.cookies[key].empty? session_id = (CGI.parse(cgi.env_table['RAW_POST_DATA'])[key] rescue nil) || (CGI.parse(ENV['QUERY_STRING'] || cgi.query_string)[key] rescue nil) cgi.params[key] = session_id unless session_id.blank? end initialize_without_session_key_fixation(cgi, options) end end end end end alias :transit_sid :trans_sid end end
CgiRequestのinitializeを拡張しているのは、コメントにあるとおり
# FastCGI環境では(どういうわけか) cgi.query_string でクエリ文字列を取得できないので # ENV['QUERY_STRING'] に代入しておく。
ということらしいです。
ActionController::Baseに追加するクラスメソッドtrans_sidは
- Jpmobile::TransSidモジュールをインクルード
- コントローラーの処理後にURLのケツにセッションIDをくっつけたり、フォームがあるときはセッションIDをhiddenで追加したりしてくれます
- Transit SIDを有効にするなら
session :cookie_only => false
でセッション管理cookie限定を解除してます
ここのsessionはsessionクラスメソッドですね・・
セッションの制御の仕方について
Railsのデフォルトは:cookie_only => trueっすね
セキュリティ対策が打たれているけど、それを解除するんで
# CSRF対策への対策
ということですか。
第3回:Railsでセッションハイジャックを実体験
session_keyはconfig/environment.rbなどで指定したキー値
クライアントからcookieが送られてこなかったらPOSTデータやQUERY_STRING環境変数やクエリストリングを漁ってsession_keyを探し出してcgi.paramsに入れてやるぜえ!というところでしょうか。