[Railsチュートリアル] 9章の内容を自分なりに落とし込む

何回読んでも「あれ、今何してるんだっけ？」と分からなくなるので
特に頭がごちゃごちゃになる、rememberメソッドを作るまでの流れを
自分なりにざっくりまとめてみました。
（詳細の説明は[Railsチュートリアル]('https://railstutorial.jp/')にお任せします。）

間違っている箇所ありましたらご教示ください。

#目的
8章で行ったsessionを使ったログイン方法だとブラウザを閉じるごとにログインが必要になるので
永続的cookie(permanent cookies)を使って**ログイン情報を長く記憶しておける（ブラウザを再起動してもログインしたままにしておける）ようにする**。
単にcookieを使うだけだとセキュリティ的に問題があるので、トークンやらハッシュ化やらして、**セキュリティを強固にする**。
その後、[remember me]チェックボックスを作ってユーザーがログイン情報を保持するかどうか選べるようにする。



#出てくる用語の意味をさらっておく
「なんとなくこうだったよね」で理解していると途中でついていけなくなるので意味を改めて確認しておきましょう

####cookie
ブラウザ上に保存できる少量のデータ。
`cookies`メソッドを使ってアクセス（保存したり読み出したり）できる。
#####署名付きcookie
cookieをブラウザに保存する前に暗号化する処理。`signed`メソッドを使う。

####記憶トークン（remember token）
コンピュータが作成・管理するパスワードのようなもの。状態保存されない（毎回変わる）。
ランダムな文字列を生成して作る。

####ハッシュ値
とあるデータ（今回の場合は記憶トークン）を
なんやかんや（今回はダイジェストに変換）して、
生成した適当そうに見える値のこと。
とあるデータからハッシュ値を作ることをハッシュ化と呼ぶ。

####`attr_accessor`メソッド
インスタンス変数の値を読み書きするメソッド

attr = attribute(属性）なので、
指定したattribute(属性）へアクセスできるようにするメソッドってことかと。
下記記事がわかりやすかったです。
- [Railsから入った人へ【attr_accessor】って？]('https://qiita.com/Hassan/items/0e034a1d42b2335936e6')

####複合化
暗号化の逆。暗号を元のデータに戻すこと。



#出来上がりのイメージ

1. ユーザーがremember meにチェックを入れてログイン
2. 記憶トークンが生成される
3. ブラウザのcookiesにトークンと暗号化したユーザーIDが保存される（トークンの有効期限も設定される）
4. 併せてトークンはハッシュ化してDBに保存される
5. クライアントからリクエストがあると、
6. Webアプリケーションがcookiesに保存されたユーザーの情報（暗号化されたユーザーIDとトークン）を受け取り、
7. 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チュートリアル]('https://railstutorial.jp/')にてご確認ください。


#参考
* [Railsチュートリアル]('https://railstutorial.jp/')
* [Railsガイド　-Action Controllerの概要]('https://railsguides.jp/action_controller_overview.html#cookie')
* [Railsガイド　-Railsセキュリティガイド]('https://railsguides.jp/security.html')
* [Railsから入った人へ【attr_accessor】って？]('https://qiita.com/Hassan/items/0e034a1d42b2335936e6')