読者です 読者をやめる 読者になる 読者になる

jpmobileのtransit_sidとacts_as_authenticatedのstore_locationの相性が微妙に悪い

Rails Ruby

コントローラが

  • user
  • welcome

というコントローラが2つあり、userはacts_as_authenticatedで生成した
コントローラだとします。
welcomeは認証が必要で、

before_filter :login_required

で、認証していない場合は/user/loginにリダイレクトされます。
通常の挙動だと、

  1. /welcome/indexを要求
  2. session[:return_to]に"/welcome/index"をセットし、/user/loginにリダイレクト
  3. /user/loginで認証が通ると、そこでredirect_back_or_defaultを呼ぶ
  4. session[:return_to]に"/welcome/index"が入っているので、そこにリダイレクト

これが一般的な流れになります。
しかし、携帯を使ってsession_idをURLに引き回している場合に
redirect_back_or_defaultで戻りたいURLは
"/welcome/index?_session_id=f3b8cbf9d73a222efe97a1a7b13ca1bc"
という感じで、session_idがくっついた状態のはずです。
session_idがないところにリダイレクトしてもまた認証が通らずに
/user/loginに戻ってしまいます。
これを修正すべく調べたところ、一番楽な方法は
lib/authenticated_system.rbのdef store_locationの中の

session[:return_to] = request.request_uri

session[:return_to] = url_for(:controller=>request.request_uri)

に直すとsession_idがくっついた状態でsession[:return_to]が作られます。
jpmobileの仕様で、URLが引き回されない場合は
session[:return_to]にもくっつかないので、これが一番いい方法なのかなと思います。
最良解ではなさそうな気がしますけどね。
コントローラ名にURLまるごと突っ込んでいるのがキモイ。

追記

session[:return_to] = url_for(request.request_parameters)

これがよさそうだ。