Rails チュートリアル九章
9.1 Remember 機能
ユーザーのウェブサイトを閉じた後でもログイン状態を有効にする機能
チェックボックスをログインフォームに追加する
9.1.1 記憶トークンと暗号化
sessionメソッドはブラウザーを閉じると消えるセッションの永続化として記憶トークンを生成しcookiesメソッドによる永続的や安全性の高い記憶ダイジェストによるトークン認証に記憶トークンを活用(トークンはパスワードと同じ秘密情報。コンピュータの作成・管理する情報)
cookiesメソッド
自動的に安全性は高くならない。セッションハイジャックの攻撃を受けやすくなるセッションハイジャックは記憶トークンを盗みログインすること。
永続セッションを生成
記憶トークンにはランダムな文字列を生成して用いる。
ブラウザのcookiesにトークンを保存するときには、有効期限を設定する。
トークンはハッシュ値に変換してからデータベースに保存する。
ブラウザのcookiesに保存するユーザーIDは暗号化しておく。
データモデルをアプリケーションに追加する
マイグレーションを実行
rails g migration add_remember_digest_to_users remember_digest:string
記憶トークンを決める
SecureRandom.urlsafe_base64
ランダムなトークンを繰り返す
SecureRandom.urlsafe_base64
ログイン状態の保持
user.rememberメソッドが動作するからユーザーの暗号化済みIDと記憶トークンをブラウザの永続cookiesに保存して永続セッションのじゅんびができた記憶トークンと記憶ダイジェストを比較するauthenticated?メソッド
をUserモデルの中に置く
def authenticated?(remember_token)
BCrypt::Password.new(remember_digest).is_password?(remember_token)
end
記憶トークンcookieに対応するユーザーを返す
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
ユーザーを忘れる
user.forgetメソッド
def forget
update_attribute(:remember_digest, nil)
end
# 永続的セッションを破棄する
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
9.1.4 2つの目立たないバグ
ユーザーがログイン中のみログアウトさせる
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
user && user.authenticated?(cookies[:remember_token])
9.2 remember チェックぼっくす
チェックボックスでログイン状態にしておく
<%= f.label :remember_me, class: "checkbox inline" do %>
<%= f.check_box :remember_me %>
<span>Remember me on this computer</span>
<% end %>
チェックボックスの送信結果を処理する
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
この記事が気に入ったらサポートをしてみませんか?