Railsチュートリアル第8章と第9章でログイン機能を学ぶ 復習(後編) Day 18/30
こんにちは、たわらです。
第9章の振り返りをします。コードの意味を理解するのに手一杯で、自分が何をしているのかがわからなくなります。コピペなので、指示通りにアプリは作れますが、力になっているとは言えません。
実際にプロダクトを作る段にならないと血肉にはならないでしょう。とはいえ、学習中の言語化は重要です。ということで、なんとか言葉にしてみました。
学んだこと
第9章の目的は、ブラウザにユーザー情報を記憶させて、ブラウザの再起動した後でもすぐにログインができるような機能を実装することです。
remember me機能というそうです。ユーザーがログアウトを実行しないかぎり、ログイン状態を維持することができます。
そのような永続セッションを実現するには、暗号化されたユーザーIDと記憶トークンなるものを利用します。
ざっくり説明すれば、ブラウザに保存された、ユーザーIDを受け取り、データベース上で、そのIDで紐づく記憶トークンを特定し、2つの記憶トークンをマッチさせることで、ログインできるようにする、という流れです。
まず、データベースに記憶トークンを格納するカラムを追加します。ただし、記憶トークンはハッシュ化させるので、追加する属性の名前はremember_digestという名前にします。
【1】記憶トークンには、SecureRandomモジュールにあるurlsafe_base64メソッドを活用します。トークン生成用のメソッドをUserクラスにメソッドとして追加します。
【2】そしてこのメソッドから生まれたランダムな文字列に関連するダイジェストを作成し、データベースの値を更新するメソッドをさらに追加します。
【3】最後に、渡されたトークンがダイジェストと一致したらtrueを返すようなauthenticated?メソッドをUserクラスにメソッドとして追加します。
このメソッドのなかで、BCryptを使ってトークンとダイジェストが一致するかを確認します。
ログインをするためのcreateアクションを作成する
次に、ユーザーの記憶トークンをデータベースとcookiesに格納するrememberメソッドを追加する。
rememberメソッドは次のようにsession_helperに定義します。
1 userの記憶トークンをダイジェストした値をDBに格納する【2】メソッドを実行
2 cookiesに暗号化されたユーザーidと記憶トークンを格納する
これで、ログインページからログインしたユーザーは永続セッションに成功しました。
ただ、これでは8章の際に定義した、現在のユーザーを返すcurrent_userメソッドは一時セッションしか対応していないので再定義をする必要がある。
今のままでは現在のログイン中ユーザーがいない場合、全部sessionID(一時的なid)がcookieとして保存されてしまう。
永続的セッションを有効化するため、session[:user_id]が存在すれば一時セッションからユーザーを取り出し、それ以外の場合はcookies[:user_id]からユーザーを取り出して、対応する永続セッションにログインする必要がある。
参考
※ここは完全に理解ができていないがとりあえず進む。
ユーザーのログアウトを実装する
ユーザーモデルに、データベースの記憶ダイジェストの値をnilに更新するforgetメソッドを追加する。
次に、このforgetメソッドと、cookiesのユーザーidと記憶トークンを消去するメソッドを中身とする、forgetメソッドを作成する。
※前者のforgetメソッドはDBの書き換え、後者のforgetメソッドはインスタンス変数への働きかけであることが違うのだ!
最後に、すでに定めてあるlog_outメソッドに後者のforgetメソッドを追加して完了する。
remember meのチェックボックスを作成する
ログインする際に、ブラウザにユーザー情報を保存するかどうか、つまり永続セッションするかどうかを尋ねる仕様にする。
createアクション内で、チェックボックスがオンかオフか、つまりparams[:remember_me]が1 or 0 かで、記憶トークンを保存するメソッドか、記憶トークンを削除するメソッドを呼び出すようにコードを書く。
困難なこと、とその対処法
・テストがわからなくなってきた
とりあえず最後まで走ってみることにします。
うれしかったこと
メソッドのなかで、別のメソッドを使うことがよくある。その際、そのなかで使用するメソッドはモジュールに逃がすことで、コードをすっきりさせられることがわかった。当たり前といえば当たり前だけど。
読んでくださったかた、ありがとうございます。
たわら
この記事が気に入ったらサポートをしてみませんか?