🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

1回答

915閲覧

rails tutorial 9章 db上のトークンを照合するメソッドの理解

ketyan

総合スコア22

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2019/10/11 10:00

###rails tutorial 9章 9.1.2節
rails tutorial 9.1.2節のリスト9.6に記述されている、
authenticated?メソッドについて質問させていただきます。

model

1class User < ApplicationRecord 2 attr_accessor :remember_token 3 4# 渡された文字列のハッシュ値を返す 5 def User.digest(string) 6 cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : 7 BCrypt::Engine.cost 8 BCrypt::Password.create(string, cost: cost) 9 end 10 11 # ランダムなトークンを返す 12 def User.new_token 13 SecureRandom.urlsafe_base64 14 end 15 16 # 永続セッションのためにユーザーをデータベースに記憶する 17 def remember 18 self.remember_token = User.new_token 19 update_attribute(:remember_digest, User.digest(remember_token)) 20 end 21 22 # 渡されたトークンがダイジェストと一致したらtrueを返す 23 def authenticated?(remember_token) 24 BCrypt::Password.new(remember_digest).is_password?(remember_token) 25 end

ここではcookieを使ったユーザーの照合のために
User.new_tokenメソッドで生成したトークンを、
User.digest(string)メソッドでハッシュ化し、
rememberメソッドでデータベースのremember_digestカラムに保存しています。

この流れで生成されたremember_digestとremember_tokenを照合して
ユーザー認証を行うと考えているのですが、
だとするとauthenticated?メソッドはどんな役割があるのでしょうか。

解説ではtokenとdigestを照合し、一致すればtrueを返すとありますが、
メソッド内のremember_tokenはローカル変数であり、userインスタンスとは全く関係が無いように思えます。

どなたか解説をお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

リスト 9.9: 永続的セッションのcurrent_userを更新する red
app/helpers/sessions_helper.rb

ここまでくると初めてauthenticated?メソッドが使用されるようですね。
そこでは user.authenticated?(cookies[:remember_token]) という使われ方になっており、どうやらブラウザに保持されたcookieのtoken情報が引数として渡されるようです。

そして、照合相手はDBに保存されたuserレコードのremember_digest属性ですね。

そうすると、動作としては「DBの情報」と「cookieに保存された情報」を照合し、両者が一致していれば同一ユーザーと判断して true を返す、そういう機能を持っていそうです。


そのあとどう話が進んでいくかはわかりませんが、remember_meに関連する問題なので、おそらく true が返却されたときはログイン済み(authenticated)として、ログイン後の画面に遷移させるために、この処理が使用されそうです。

投稿2019/10/11 11:39

siruku6

総合スコア1382

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ketyan

2019/10/11 13:47

siruki6さん、ご回答ありがとうございます。 authenticated?の式が評価され、trueならログインというのは理解しております。 私の頭の中で、tokenはUser.new_tokenメソッドが生成し、その値をUser.digestがハッシュ化したものがdigestだと認識しております。 しかし、リスト9.6の下にある >authenticated?メソッドのローカル変数として定義したremember_tokenは、 >リスト 9.3のattr_accessor :remember_tokenで定義したアクセサとは異なる点に注意してください という記述から、User.new_tokenメソッドで生成したtokenと authenticated?メソッドのローカル変数であるremember_tokenは別物であり、 digestと比較するするべきはアクセサの方のtokenではないか、と考えています。 それとも、二つのトークンは同じものだったりするのでしょうか。 どの点で私の理解が足りていないのか、ご指摘いただければ幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問