2013年1月28日月曜日

Railsのdeviseを使ってみる ~自動生成された標準の画面を調べよう5~

というわけで前回の続きで画面を表示させてみる。
残りは
  • 3. ユーザ登録キャンセル
  • 5. パスワード更新画面表示
の2つ。
#前回は間違えて3より先に4をやってしまっていたらしい。

というわけでログインしている状態で上記2つを表示させてみる。


3. ユーザ登録キャンセル

でやってみたところ、起点画面に遷移して
You are already signed in.
と表示されてしまった。
むむむ。整理すると。
  • ログインしていない状態➡ログイン画面(Sing_in)画面へ飛ばされる
  • ログインしている状態➡『おまえはもうじゅうぶんにろぐいんしている』
と言われる。
この挙動から見るにこの画面は、『ログインしていない状態でアクセスするのが正しい』、ように見える。
#エラーメッセージが出るのがログイン済の状態なので。
悩んでもしょうがないのでコードを読んでみることにする。
/devise_users/cancel のアクションは devise/registrations#cancel であり、そのソースは下記。
#うちはRubyMineで開発しているので Command + N のクラス名を検索したところ、 devise/RegistrationController が発見できたのでそれで見た。
#テキストエディタの人はgemのdeviseのフォルダ以下(あるのかどうかもわからんけど)でも探しにいくことになるのでは無いかと推測。
#例によって日本語コメントはコチラで付記。
  
  # GET /resource/cancel
  # Forces the session data which is usually expired after sign
  # in to be expired now. This is useful if the user wants to
  # cancel oauth signing in/up in the middle of the process,
  # removing all OAuth session data.
  # セッションデータ(普通はSign_in後に破棄される)を直ちに破棄します。
  # これはユーザがOAuthのSign_in,Sign_up の処理を中断するのにベンリです。
  def cancel
    # sessionからdevise… というキーのデータ全部消す
    expire_session_data_after_sign_in!
    #registrasion#new へリダイレクト
    redirect_to new_registration_path(resource_name)
  end

うーん、完全に推測だけど以下のカンジだろうか。
  1. 認証方式をOAuthにする
  2. この状態で認証しようとするとdeviseは入力された情報をsessionに溜め込む
  3. その後OAuth認証を行おうとする
  4. で、途中で辞めたくなった場合に中途半端にsessionにOAuthのデータが残るとセキュリティ的にいまいちなので消す
ともあれとりあえずこの画面を後回しにするべき(なんか深くはまりそう&これより先に普通に使う画面について勉強した方がいい)ということだけはわかった。

5. パスワード更新画面

これも『こんなのログイン後にアクセスしたらパスワード変更画面が出るあれだろ、ハハハ』とか思ってアクセスしたところ。

起点画面に遷移して
You are already signed in.
と表示されてしまった。
あべし。

やむなしと思いなしてpassword#editの中身をのぞいてみると。

  # GET /resource/password/edit?reset_password_token=abcdef
  def edit
    self.resource = resource_class.new
    resource.reset_password_token = params[:reset_password_token]
  end

とほぼノーヒント状態。

#ちなみに後でわかるがこれはノーヒントなどではなく、もうクリティカルな回答そのものが提示されていた。

で、さんざん悩んだあげくgoogl先生に聞いてみたところ
コチラのすばらしいブログhttp://blog.livedoor.jp/nizoraul/archives/3622073.html
が同じようなこと(deviseの解説)をなされていたので、読み進めていくと以下の記載が。

そのあとで、自分のメールのユーザー作って、パスワードを綺麗サッパリ忘れます。 
 そのあとで、「Forgot your password?」からメールアドレスを入力して「send me reset password instructions」をクリックすると... 

おおぅなにやら英文のメールが届きました。そのなかの 
Change my passwordというのがあり、クリックするとパスワード変更ページが開きます。URLを見ると?reset_password_token=****のパラメータが設定されてますねぇ。



あー、わかった、この画面って。

  1. パスワードを忘れた人がパスワードリセット申し込み画面でメールアドレスを入力してリセットを申し込む
  2. 入力したアドレスにリセット画面のリンクが届く
  3. 該当リンクの画面を開いてパスワードリセットを行う
ってやつだ。
となるとそのリンクは  devise_users/password/edit?reset_password_token=zzzz
の的なヤツと推測できる。
#さっきのpassword#editの冒頭に思いっきり GET /resource/password/edit?reset_password_token=abcdef って書いてあるじゃん…、というのがクリティカルな回答でした。

でそのtokenはメールに書いてあるんだろうけど、『そのリンクの正当性を確認するためにはサーバ側にもその値を持っていなければならない』、だろうから多分DBに持ってるはず。
➡ DBのdevise_usersテーブルをのぞいてみるとそのものズバリ reset_password_token というカラムがいる。
で、パスワードリセットを実行したレコードにだけreset_password_token の値がセットされている。

ここまでくればやることはただ一つ。
/devise_users/password/edit?reset_password_token={DBに保存してあるトークン}
にアクセス。
#{}内は置換する。

でたー!



やったー。
苦労したので感慨一入だー。

という訳で今回はココまで。
次回は今までわかったこと、とくに画面遷移を整理して、実際に使う場合のやり方を明らかにしよう。

0 件のコメント:

コメントを投稿