何回読んでも「あれ、今何してるんだっけ?」と分からなくなるので
特に頭がごちゃごちゃになる、rememberメソッドを作るまでの流れを
自分なりにざっくりまとめてみました。
(詳細の説明はRailsチュートリアルにお任せします。)
間違っている箇所ありましたらご教示ください。
#目的
8章で行ったsessionを使ったログイン方法だとブラウザを閉じるごとにログインが必要になるので
永続的cookie(permanent cookies)を使ってログイン情報を長く記憶しておける(ブラウザを再起動してもログインしたままにしておける)ようにする。
単にcookieを使うだけだとセキュリティ的に問題があるので、トークンやらハッシュ化やらして、セキュリティを強固にする。
その後、[remember me]チェックボックスを作ってユーザーがログイン情報を保持するかどうか選べるようにする。
#出てくる用語の意味をさらっておく
「なんとなくこうだったよね」で理解していると途中でついていけなくなるので意味を改めて確認しておきましょう
####cookie
ブラウザ上に保存できる少量のデータ。
cookies
メソッドを使ってアクセス(保存したり読み出したり)できる。
#####署名付きcookie
cookieをブラウザに保存する前に暗号化する処理。signed
メソッドを使う。
####記憶トークン(remember token)
コンピュータが作成・管理するパスワードのようなもの。状態保存されない(毎回変わる)。
ランダムな文字列を生成して作る。
####ハッシュ値
とあるデータ(今回の場合は記憶トークン)を
なんやかんや(今回はダイジェストに変換)して、
生成した適当そうに見える値のこと。
とあるデータからハッシュ値を作ることをハッシュ化と呼ぶ。
####attr_accessor
メソッド
インスタンス変数の値を読み書きするメソッド
attr = attribute(属性)なので、
指定したattribute(属性)へアクセスできるようにするメソッドってことかと。
下記記事がわかりやすかったです。
####複合化
暗号化の逆。暗号を元のデータに戻すこと。
#出来上がりのイメージ
- ユーザーがremember meにチェックを入れてログイン
- 記憶トークンが生成される
- ブラウザのcookiesにトークンと暗号化したユーザーIDが保存される(トークンの有効期限も設定される)
- 併せてトークンはハッシュ化してDBに保存される
- クライアントからリクエストがあると、
- Webアプリケーションがcookiesに保存されたユーザーの情報(暗号化されたユーザーIDとトークン)を受け取り、
- DBのユーザーIDとハッシュ化されたトークンに一致するかを確認
#ざっくりした手順
#####①「ハッシュ化した記憶トークン」を保存しておくカラム[ remember_digest ]を作成
#####②ランダムなトークンを返すメソッドUser.new_token
を用意
※インスタンスに対してこのメソッドを使うことはないのでクラスメソッドにする
#####③渡された文字列をハッシュ化するメソッドUser.digest
を用意(8章で作ってあった)
※こちらもインスタンスに対してこのメソッドを使うことはないのでクラスメソッドにする
#####④トークンにアクセスできるように、[ remember_token ]という仮想の属性を用意
* User.new_token
で作成したトークンを入れておきトークンにアクセスできるようにする
* 生のトークンをDBに保存したくないので[ remember_token ]という仮の箱を用意するイメージ
* attr_accessor
を使うことで[ remember_token ]という仮想の属性を用意することを実現する
class User
attr_accessor :remember_token
#####⑤トークンをハッシュ化してDBに保存するメソッドremember
を用意
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
ここで何が起こってるかというと
例えば、@user
さんがログインした時、
@user.remember_token
にUser.new_token
で生成されたトークンを代入(保存)。
(attr_accessor :remember_token
で、@userの[ remember_token ]をいじくれるようになってる)
update_attribute
:指定された属性を上書きメソッド で、
@user
のデータベースの[ remember_digest ]カラムに、
User.digest(remember_token)
で[ remember_token ]をハッシュ化した値
を保存してます。
#####⑥渡されたトークンとDBに保存されたダイジェスト(=ハッシュ化されたトークン)が同じが確認(認証)するメソッドauthenticated?
を用意
def authenticated?(remember_token)
BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
ここで出てくるremember_tokenはattr_accessor
で定義された[ remember_token ]とは別物。
ただのメソッド内のローカル引数なので、ここの名前を例えばn
とか適当な名前に変えても動く。
#####⑦ユーザー情報(ユーザーIDと記憶トークン)を永続的cookieに保存するremember
メソッドをsessions_helper.rbに用意
#####⑧remember
メソッドをsessions_controller.rbに設置してログインしたらcookiesにユーザー情報が保存されるようにする
#####⑨current_userをcookieを使った場合にも使えるように変更する
その後、このままだとログアウト出来なくなるのでログアウトの処理も追記したり、
remember meのチェックボックスを用意してユーザーがcookieを使うか選択できるようにしたりしていきます。
詳細はRailsチュートリアルにてご確認ください。
#参考