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をパラメータに埋め込む様にしたいなぁ。
斎藤ただし
一行が長いと思うので、もうちょっと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)
masuidrive
ありがとうございますー。
確かにそうですね、結構継ぎ足しのコードだったので。
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)
フェルテス
なぜかこちらにはPstoreでしか動いていません。
SQLSessionStoreとかMemcachedとかだとSession IDが空になってしまいます。
dara
trunkに修正をコミットしてみました。手元ではSQLSessionStoreでも動作するようです。