Posted filed under Ruby on Rails.

Cookieが使えないDoCoMoなどの端末で、uriにセッションキーを追加するtrans_sidが、Rails 2.0系で動かないっていう話があったので、気分転換に手を動かしてみました。

http://dev.rubyonrails.org/browser/tags/rel_2-0-2/actionpack/lib/action_controller/cgi_ext/session.rb
Railsのセッションは、Ruby標準のCGI::Sessionを使っています。ここでSessionを生成する時にCGIのオブジェクトから、クッキーやパラメータを見てセッションを生成してます。
そこで、このセッション生成のときを調べてみると、CGI#paramsが空でパラメータが渡っていません。

http://dev.rubyonrails.org/browser/tags/rel_2-0-2/actionpack/lib/action_controller/cgi_ext/query_extension.rb
CGIの生成を追っていると、そもそも生成時にCGI#paramsを{}で上書きしています。

これは、CSRF対策のようです。これを上書きするのもちょっとなんな気がするので、セッション生成時にパラメータを再構築する様にしてみます。

jpmobile/lib/jpmobile/trans_sid.rb に下記のパッチを追加してください。

class ::CGI #:nodoc:
  class Session #:nodoc:
    alias_method :initialize_without_uri_session_key, :initialize
    def initialize(cgi, options = {})
      cgi.params[options['session_key']] ||= ENV['RAW_POST_DATA'] ? CGI.parse(ENV['RAW_POST_DATA'])[options['session_key']] : CGI.parse(cgi.query_string)[options['session_key']] if @cgi.cookies[options['session_key']].empty?
      initialize_without_uri_session_key(cgi, options)
    end
  end
end

このままだと、jpmobileをインストールするだけで、セッションキーをパラメータで受け取る様になってしまいます。
本当は最低でもtrans_sidが起動された場合にのみ、このパッチが走る様にしないとな。
携帯用にするなら、携帯からのアクセスの場合のみURIパラメータでセッションキーを受け取る様にしたいなぁ。

このパッチは、作者のShidara君に送ってあるので、数日中に取り込まれると思います。

続いて、CookieStoreをパラメータに埋め込む様にしたいなぁ。

5 Responses to “jpmobileのtrans_sidがRails2.0で動かなかったのでパッチを作ってみた”

  1. 斎藤ただし

    一行が長いと思うので、もうちょっとDRYにしませんか。

    key = options[‘session_key’]
    query = ENV[‘RAW_POST_DATA’] || CGI.parse(cgi.query_string)
    cgi.params[key] ||= CGI.parse(query)[key] if @cgi.cookies[key].empty?
    initialize_without_uri_session_key(cgi, options)

  2. masuidrive

    元のコードにおかしい所があったので、ちょっと直してみました。

    key = options[‘session_key’]
    query = ENV[‘RAW_POST_DATA’] || cgi.query_string || ”
    cgi.params[key] = CGI.parse(query)[key] if cgi.cookies[key].empty?
    initialize_without_uri_session_key(cgi, options)

  3. フェルテス

    なぜかこちらにはPstoreでしか動いていません。
    SQLSessionStoreとかMemcachedとかだとSession IDが空になってしまいます。

  4. dara

    trunkに修正をコミットしてみました。手元ではSQLSessionStoreでも動作するようです。