はじめに
Railsチュートリアルの第9章が終わりました。
ポイントだけメモしておきます。
トークンの考え方
永続的なログインを実装するために、cookieというものに値を保持します。
しかし、そのままログイン情報を保持してしまうと、情報を盗み見られたりするとサイバー攻撃に繋がってしまうため、複雑にして保持する必要があります。
流れを簡単にまとめると以下のようなイメージです。
・ログイン時、ユーザーIDを暗号化したものと、ランダムな文字列トークンをcookieに保持
・ランダムな文字列トークンをハッシュ化して、ユーザーテーブルに保持
・ログインチェック時、cookieからユーザーIDを取り出してテーブル検索
・取得したデータのトークンとcookieのトークンのハッシュ値を比較
トークンの生成
以下の記述で、64種類の文字(A–Z、a–z、0–9、"-"、"_")からランダムに22文字生成してくれます。
SecureRandom.urlsafe_base64
モデルの仮想の属性
モデルにトークンを保持する際、データベースに保存せずに値を取得したいです。
その際に、以下のようにattr_accessor
でゲッターとセッターを定義して仮想の属性を定義できます。
rememberメソッドの2行目は、トークンをハッシュ化してデータベースに保存しています。
class User < ApplicationRecord
attr_accessor :remember_token
# ランダムなトークンを返す
def User.new_token
SecureRandom.urlsafe_base64
end
# 永続セッションのためにユーザーをデータベースに記憶する
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
end
cookieの保持
実際にcookieに値を保持する際は、sessionと同じようにハッシュの形式で値を設定します。
以下のように、expires
によって有効期限を設定できます。
cookies[:remember_token] = { value: remember_token,
expires: 20.years.from_now.utc }
また、以下のようにpermanent
メソッドを使用することで、自動的に20年を設定してくれます。
cookies.permanent[:remember_token] = remember_token
ユーザーIDを保持する際など、暗号化して格納する場合は、signed
メソッドを使用します。
cookies.signed[:user_id] = user.id
2つを合わせて記述すると以下のようになります。
cookies.permanent.signed[:user_id] = user.id
取り出す際は同じようにcookies.signed[:user_id]
で複合化して取得できます。
cookieの削除
cookieを削除する際は、delete
を使用します。
cookies.delete(:user_id)
cookies.delete(:remember_token)
チェックボックス
form_for
の中にチェックボックスを記述する際は、f.check_box
で記述します。
以下のように、ラベルの内側に書くことで、チェックボックスと文字列をひとまとまりにしています。
<%= form_for(:session, url: login_path) do |f| %>
...
<%= f.label :remember_me, class: "checkbox inline" do %>
<%= f.check_box :remember_me %>
<span>Remember me on this computer</span>
<% end %>
...
<% end %>
値を取得する際は、チェックボックスがオンの時1
、オフの時0
になります。