Rails 6.0でアプリを開発 基本の流れ⑩ アカウントの有効化
今回はメール認証でアカウントを有効化する機能を実装するためのメモ
実現したいこと
新規登録の途中にアカウントを有効化する。本当にそのメールアドレスの持ち主かどうか確認できるようにする。
アカウント有効化の流れ
①有効化トークンやダイジェストを関連付けた状態で
②有効化トークンを含めたリンクをユーザーにメール送信
③ユーザーがそのリンクをクリックすると有効化
実装するには
①ユーザーの初期状態は有効化されていない状態にする
②登録されたときに有効化トークンとそれに対応する有効化ダイジェストを生成
③有効化ダイジェストはDBに保存。有効化トークンはメアドと一緒にユーザーに送信する有効化用のメールのリンクに仕込む
④ユーザーがメールのリンクをクリックすると、アプリケーションはメアドをキーにしてユーザーを探しDB内に保存しておいた有効化ダイジェストと比較してトークン認証をする
⑤ユーザーを認証出来たらユーザーのステータスを「有効化されていない」から「有効化済み」に変更
1)AccountActivationコントローラーの作成
$ rails g controller AccountActivations
2)リソースをルーティングに追加
・editのみ追加
これによって生成されるURLはedit_account_activation_url(token)
※ユーザーはメールによってアクセスするのでpathではなくurlを使用する
3)usersテーブルに3つのデータモデルを追加する
①$ rails g migration add_activation_to_users activation_digest:string activated:boolean activated_at:datetime
②activated属性のデフォルトの論理値をfalseにしておく
※上記実装するには①
rails db:migrate
③beforeコールバックでオブジェクトが作成されたときのみコールバックが呼び出されるようにする。
※有効化をmustの作業にするため
ⅰ)Userモデルに有効化のコードを追加
・有効化トークンを仮想の属性とする
・create_activation_digestというbeforeコールバックをセット
・メアドを小文字にするメソッドもメソッド参照型にする
ⅱ)private内にコールバックメソッドを定義
メアドを小文字にするメソッドもここに追加
④サンプルユーザーを最初から有効化しておく
⑤fixtureのユーザーも有効化しておく
※全部入らず、全員につける
⑥DBの初期化とサンプルデータの再生成
$ rails db:migrate:reset
$ rails db:seed
4)送信メールのテンプレを作成
①userメーラーの生成
$ rails g mailer UserMailer account_activation password_reset
②アプリケーションメーラーのfromアドレスのデフォルト値を更新
③アカウント有効化リンクをメール送信する設定を記述
※ここでrails6の追加機能が利用できる様子。下記参照
Rails6 のちょい足しな新機能を試す61(ActionMailer template_name編) - Qiita
④有効化トークン認証のためにユーザーに送るリンクにメアドとトークンを含める
⑤ビューの作成
ⅰ)テキストビュー
ⅱ)htmlビュー
5)送信メールのプレビューを見る
①development環境のメール設定をする
②アカウント有効化のプレビューメソッドを修正
・user変数が開発用DBの最初のユーザーになるように定義
・それをUserMailer.account_activationに引数として渡す。
・user.activation_tokenにも代入する
サーバー起動後、上部に記載してあるURLにアクセスするとプレビューが確認できる。
6)送信メールのテスト
①現在のメールの実装をテスト
CGI.escape(user.email)でテスト用のユーザーのメアドをエスケープできる。
②テストのドメインhostを設定
テストを通すためにテストファイル内のドメイン名を正しく設定する。
7)ユーザーのcreateアクションを更新
①ユーザーをsaveするとメールを送信しrootページにユーザーを飛ばす、かつ、ユーザーはログインしない。
②メールでリンクを踏むまでログインはしないので、関連した失敗してしまうテストを一時的にコメントアウトする。
③実際に開発環境でユーザー登録をすると
ルートに飛ばされこのようなメッセージが出る
サーバーのログを確認すると
※後ほどこのURLで有効化させる。
8)authenticated?メソッドの編集(有効利用)
①メソッドを抽象化するsendメソッドの設置
トークンがダイジェストと一致したらtrueを返すauthenticated?メソッドの引数を動的にする
②authenticated?メソッドを使用している部分を編集
ⅰ)current_userメソッド内
ⅱ)userのtest内のauthenticated?メソッド
9)アカウントを有効化するeditアクションの設定
これで、サーバーログ内で確認出来たリンクを使用して有効化できる。
リンクをべた貼りすると
10)有効でないユーザーはログインできないようにする
11)アカウント有効化の統合テスト
12)リファクタリング
①Userモデルにユーザー有効化メソッドを追加
・アカウントを有効にするactivateメソッド
・有効化用のメールを送るsend_activation_emailメソッド
ユーザーモデル内に記述しているためuserという記法を用いない(self or なしでよい)
②ユーザーモデルオブジェクトからメールを送信する
※①で生成したsend_activation_emailメソッドを呼び出す
③ユーザーモデルオブジェクト経由でアカウントを有効化
※①で生成したactivateメソッドを呼び出す
④indexページとshowページでは有効化されたユーザーのみを表示するように設定
13)HerokuアドオンSendGrid
本番環境からのメール送信はSendGridを使用する
①アドオンをアプリケーションに追加
$ heroku addons:create sendgrid:starter
②Railsのproduction環境でsendGridを使う設定をする
③環境変数を設定
SendGridの場合環境変数はアドオンが自動的に設定してくれる。
それらを表示して確認したいときには下記のコマンド
$ heroku config:get SENDGRID_USERNAME
$ heroku config:get SENDGRID_PASSWORD
以上で終了(^^)/