はじめに
独学でrails tutorialを進めていく過程を投稿していきます。
進めていく上でわからなかった単語、詰まったエラーなどに触れています。
個人の学習のアウトプットなので間違いなどあればご指摘ください。
初めての投稿なので読みにくいところも多々あるかと思いますがご容赦ください。
第9章 発展的なログイン機構
9.1.1 記憶トークンと暗号化
attr_accessorの復習
参考
https://qiita.com/Hassan/items/0e034a1d42b2335936e6
.remember_tokenが使えるようになります(remember_token属性が扱えるようになった)
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
最後の(remember_token)はself.が省略されています。
9.1.2 ログイン状態の保持
BCrypt::Password.new(remember_digest) == remember_token
このコードをじっくり調べてみると、実に奇妙なつくりになっています。bcryptで暗号化されたパスワードを、トークンと直接比較しています。(rails tutorial 9章より引用)
ふむふむ、確かに、、、
==で比較する際にダイジェストを復号化しているのでしょうか。
しかし、bcryptのハッシュは復号化できないはずなので、復号化しているはずはありません。(rails tutorial 9章より引用)
なるほど、、では何が起こっているのでしょう?
BCrypt::Password.new(remember_digest).is_password?(remember_token)
どうやら上の2つのコードは同じ意味のようです。
また、is_password?メソッドでオブジェクトと渡された引数の検証をし、一致している場合trueを返しているようです。
9.3.2 [Remember me]をテストする
また、リスト 9.24で定義したlog_in_asヘルパーメソッドでは、session[:user_id]と定義してしまっています。このままでは、current_userメソッドが抱えている複雑な分岐処理を統合テストでチェックすることが非常に困難です。(rails tutorial 9章より引用)
ん?なぜでしょう?
A.
統合テストではsessionメソッドが扱えないから
def log_in_as(user)
session[:user_id] = user.id #使えない
end
test "current_user returns right user when session is nil" do
assert_equal @user, current_user
assert is_logged_in?
end
このcurrent_userとは
current_userメソッドが実行された上でモデルオブジェクトとなっているようです。多分、、、
つまり
log_in user
なども行われており、sessionメソッドも実行されているのだと思います、、、
def current_user
if user_id = session[:user_id] #false
@current_user ||= User.find_by(id: user_id)
elsif user_id = cookies.signed[:user_id] #true
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user #ログインされる
@current_user = user
end
end
end
current_userメソッドは戻り値にモデルのインスタンスを返すモデルオブジェクト。
test "current_user returns nil when remember digest is wrong" do
@user.update_attribute(:remember_digest,User.digest(User.new_token))
assert_nil current_user
end
@user.update_attribute(:remember_digest, User.digest(User.new_token))
remember_digestを新しいものに更新。
assert_nil current_user
は
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]) #falseとなりcurrent_userはnilとなる
log_in user
@current_user = user
end
end
end
if user && user.authenticated?(cookies[:remember_token])
こちらの検証に置いてcurrent_userがnilとなるか確かめています。
終わりに
こちらの章ではエラーで躓くことも少なく、内容もよく理解出来ました。