Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails Tutorial 第11章 #78

Closed
kenta0425 opened this issue Jan 31, 2021 · 1 comment
Closed

Rails Tutorial 第11章 #78

kenta0425 opened this issue Jan 31, 2021 · 1 comment
Assignees

Comments

@kenta0425
Copy link
Collaborator

WHY

WHAT

  • 第11章のアカウントの有効化を理解し、完成すること
@kenta0425
Copy link
Collaborator Author

アカウントの有効化

アカウントの有効化
新規登録の途中に、本当にそのメールアドレスの持ち主なのか確認できるようする

  1. ユーザーの初期状態は「有効化されてない」(unactivated) にしておく
  2. ユーザー登録が行われた時に、有効化トークンと、それに対応する有効化ダイジェストを生成する
  3. 有効化ダイジェストはデータベースに保存しておき、有効化トークンはメールアドレスと一緒に、ユーザーに送信する有効化用メールのリンクに仕込んでおく
  4. ユーザーがメールのリンクをクリックしたら、アプリケーションはメールアドレスをキーにユーザーを探し、データベース内に保存しておいた有効化ダイジェストと比較することでトークンを認証する
  5. ユーザーを認証できたら、ユーザーのステータスを「有効化されてない」から「有効化済み」(activated)に変更する

Account Activationのデータモデル
仮想的な属性を使ってハッシュ化した文字列をデータベースに保存するようにする
ハッシュ化した文字列を保存するactivation_digestとboolean型のactivatedカラムを作る

  • boolean型
    • trueかfalseをいれるカラムの型

メソッド参照

  • before_create
    • ユーザーを作成する前に指定されたメソッドを探し実行してくれる
  • 新しいユーザーが定義されると、activation_token属性とactivation_digest属性が得られ、activation_digest属性はすでにデータベースのカラムと関連付けされているので、ユーザーが保存される時に保存される

アカウント有効化のメール送信
Action Mailerライブラリを使ってUserのメイラーを追加し、Usersコントローラのcreateアクションで有効化リンクをメール送信する

  • app/mailers/application_mailer.rb
default from: "[email protected]"  # 送信元のメールアドレスを設定

app/mailers/user_mailer.rb

mail to: user.email, subject: "Account activation"
# subjectキーでメールの件名を設定
  • Rails サーバーでユーザーをメールアドレスで検索して有効化トークンを認証できるようにする為に、リンクにメールアドレスとトークンを含めておく
  • @記号はURLで扱えない文字なので、%40になる

送信メールのプレビュー
Rails では特殊なURLにアクセスすると、メールを実際に送信しなくてもメッセージをその場でプレビューすることができる

コントローラにメーラー追加

  • createアクションに追加する
  • deliver_nowで今すぐ送信できる
UserMailer.account_activation(@user).deliver_now

authenticated?メソッドの抽象化

  • @user.authenticated?を複数のtokenとdigestに対応できるようにする
  • メタプログラミングという、受け取ったパラメータに応じて呼び出すメソッドを切り替える手法を使う
  • 名前に統一性があるので、#{認証名}_token#{認証名}_digestのようにして認証名に応じて扱うトークンをかえる
  • sendメソッド
    • 渡されたオブジェクトに「メッセージを送る」ことによって、呼び出すメソッドを動的に決めることができる
user.activation_digest
=> "$2a$10$4e6TFzEJAVNyjLv8Q5u22ensMt28qEkx0roaZvtRcp6UZKRM6N9"
attribute = :activation
user.send("#{attribute}_digest")
=> "$2a$10$4e6TFzEJAVNyjLv8Q5u22ensMt28qEkx0roaZvtRcp6UZKRM6N9"
attribute = :remember
user.send("#{attribute}_digest")
=> nil
  • authenticated?メソッドを対応できるように書き換える
    • 2番目の引数をtokenにして一般化する
def authenticated?(attribute, token)
  digest = send("#{attribute}_digest")
  return false if digest.nil?
  BCrypt::Password.new(digest).is_password?(token)
end

editアクションで有効化

  • !user.activated?は既に有効になってるユーザーが誤って再度有効化しない為に必要
if user && !user.activated? && user.authenticated?(:activation, params[:id])

有効化のテスト

  • setupメソッドで、deliveries変数を初期化にしておかないと、並行して行われる他のテストでメールが配信されたときにエラーが発生する
ActionMailer::Base.deliveries.clear
  • assignsメソッドを使うと対応するアクション内のインスタンス変数にアクセスできる
user = assigns(:user)

This was referenced Feb 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant