場当たり的にJpmobileをRails2.3に対応してみる(2) trans_sid

Jpmobileのtrans_sidをrails2.3で無理矢理動かしてみる

  • rails2.3ではセッション管理がrackのmiddlewareで入るのでCGI::Sessionをごにょごにょしなくてすむのでカット
  • session_optionsのcookie_onlyはmiddlewareのインスタンス変数になるけども、初期化時に固定されて、その後で動的に変更する方法が分からない・・(セッションを生成/復元するところを書き換えするしかないか・・?)とりあえず$RAILS_ROOT/config/initializers/session_store.rbとかでfalse固定定義で・・
  • rails2.3ではセッションオブジェクトにアクセスしない限り生成/復元が行なわれないので、どっかで(default_url_optionsで?)触る必要あり
  • セッションIDを取得するのにrails2.3ではsession.session_idは使えない。request.session_options[:id]を使う。
  • 上記以外はほぼそのまんま


jpmobile/lib/jpmobile/trans_sid.rb

if ::ActionPack::VERSION::MAJOR >=2 and ::ActionPack::VERSION::MINOR >= 3
  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対策への対策
          # {:cookie_only => false} どうやんの?
        end
      end 
      alias :transit_sid :trans_sid
    end 
  end 

  module Jpmobile::TransSid #:nodoc:
    def self.included(controller)
      controller.after_filter(:append_session_id_parameter)
    end 

    protected
    # URLにsession_idを追加する。
    def default_url_options(options=nil)
      return unless request # for test process
      return unless apply_trans_sid?
      request.session.inspect #sessionをload
      { session_key => request.session_options[:id] }
    end 

    private
    # session_keyを返す。
    def session_key
      session_key = request.session_options[:key] || '_session_id'
    end 
    # session_idを埋め込むためのhidden fieldを出力する。
    def sid_hidden_field_tag
    "<input type=\"hidden\" name=\"#{CGI::escapeHTML session_key}\" value=\"#{CGI::escapeHTML request.session_options[:id]}\" />"
    end 
    # formにsession_idを追加する。
    def append_session_id_parameter
      return unless request # for test process
      return unless apply_trans_sid?
      response.body.gsub!(%r{(</form>)}i, sid_hidden_field_tag+'\1')
    end
    # trans_sidを適用すべきかを返す。
    def apply_trans_sid?
      return false unless session
      return false if trans_sid_mode == :none
      return true if trans_sid_mode == :always
      if trans_sid_mode == :mobile
        if request.mobile?
          return !request.mobile.supports_cookie?
        else
          return false
        end
      end
      return false
    end
  end
else
  #Jpmobile 0.4.4
end