自分の手で未来を創るーlav0

自分のために、誰かのために、今ここにないもの、もっと良くしたいもの、何でも自分の手で創っていく。そして、作ったものを公開していきます

Rails 6.0でアプリを開発 基本の流れ⑩ アカウントの有効化

今回はメール認証でアカウントを有効化する機能を実装するためのメモ

f:id:kslabo51:20200310222030j:plain

実現したいこと

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

 

アカウント有効化の流れ

①有効化トークンやダイジェストを関連付けた状態で

②有効化トークンを含めたリンクをユーザーにメール送信

③ユーザーがそのリンクをクリックすると有効化

 

実装するには

①ユーザーの初期状態は有効化されていない状態にする

②登録されたときに有効化トークンとそれに対応する有効化ダイジェストを生成

③有効化ダイジェストはDBに保存。有効化トークンはメアドと一緒にユーザーに送信する有効化用のメールのリンクに仕込む

④ユーザーがメールのリンクをクリックすると、アプリケーションはメアドをキーにしてユーザーを探しDB内に保存しておいた有効化ダイジェストと比較してトークン認証をする

⑤ユーザーを認証出来たらユーザーのステータスを「有効化されていない」から「有効化済み」に変更

 

1)AccountActivationコントローラーの作成

$ rails g controller AccountActivations

 

2)リソースをルーティングに追加

・editのみ追加

f:id:kslabo51:20200309211317p:plain

これによって生成される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にしておく

※上記実装するには①

f:id:kslabo51:20200309212027p:plain

rails db:migrate

 

③beforeコールバックでオブジェクトが作成されたときのみコールバックが呼び出されるようにする。

※有効化をmustの作業にするため

 

ⅰ)Userモデルに有効化のコードを追加

・有効化トークンを仮想の属性とする

・create_activation_digestというbeforeコールバックをセット

・メアドを小文字にするメソッドもメソッド参照型にする

f:id:kslabo51:20200309213019p:plain

 

ⅱ)private内にコールバックメソッドを定義

f:id:kslabo51:20200309213151p:plain

メアドを小文字にするメソッドもここに追加

 

④サンプルユーザーを最初から有効化しておく

f:id:kslabo51:20200309213512p:plain

 

⑤fixtureのユーザーも有効化しておく

f:id:kslabo51:20200309213815p:plain

※全部入らず、全員につける

 

⑥DBの初期化とサンプルデータの再生成

$ rails db:migrate:reset

$ rails db:seed

 

4)送信メールのテンプレを作成

①userメーラーの生成

$ rails g mailer UserMailer account_activation password_reset

 

②アプリケーションメーラーのfromアドレスのデフォルト値を更新

f:id:kslabo51:20200309215752p:plain

 

③アカウント有効化リンクをメール送信する設定を記述

f:id:kslabo51:20200310193837p:plain

 

※ここでrails6の追加機能が利用できる様子。下記参照

Rails6 のちょい足しな新機能を試す61(ActionMailer template_name編) - Qiita

 

④有効化トークン認証のためにユーザーに送るリンクにメアドとトークンを含める

f:id:kslabo51:20200309221145p:plain

⑤ビューの作成

ⅰ)テキストビュー

f:id:kslabo51:20200309221821p:plain

ⅱ)htmlビュー

f:id:kslabo51:20200309221627p:plain

 

5)送信メールのプレビューを見る

①development環境のメール設定をする

f:id:kslabo51:20200310193252p:plain

 

②アカウント有効化のプレビューメソッドを修正

・user変数が開発用DBの最初のユーザーになるように定義

・それをUserMailer.account_activationに引数として渡す。

・user.activation_tokenにも代入する

f:id:kslabo51:20200310192911p:plain

サーバー起動後、上部に記載してあるURLにアクセスするとプレビューが確認できる。

6)送信メールのテスト

①現在のメールの実装をテスト

f:id:kslabo51:20200310194534p:plain

CGI.escape(user.email)でテスト用のユーザーのメアドをエスケープできる。

 

②テストのドメインhostを設定

f:id:kslabo51:20200310194852p:plain

テストを通すためにテストファイル内のドメイン名を正しく設定する。

 

7)ユーザーのcreateアクションを更新

①ユーザーをsaveするとメールを送信しrootページにユーザーを飛ばす、かつ、ユーザーはログインしない。

f:id:kslabo51:20200310201110p:plain

 

②メールでリンクを踏むまでログインはしないので、関連した失敗してしまうテストを一時的にコメントアウトする。

f:id:kslabo51:20200310201346p:plain

 

③実際に開発環境でユーザー登録をすると

f:id:kslabo51:20200310201938p:plain

ルートに飛ばされこのようなメッセージが出る

サーバーのログを確認すると

f:id:kslabo51:20200310202251p:plain

※後ほどこのURLで有効化させる。

 

8)authenticated?メソッドの編集(有効利用)

①メソッドを抽象化するsendメソッドの設置

トークンがダイジェストと一致したらtrueを返すauthenticated?メソッドの引数を動的にする

f:id:kslabo51:20200310204459p:plain

 

②authenticated?メソッドを使用している部分を編集

ⅰ)current_userメソッド内

f:id:kslabo51:20200310204137p:plain

 

ⅱ)userのtest内のauthenticated?メソッド

f:id:kslabo51:20200310204350p:plain

 

9)アカウントを有効化するeditアクションの設定

f:id:kslabo51:20200310210156p:plain

これで、サーバーログ内で確認出来たリンクを使用して有効化できる。

リンクをべた貼りすると

f:id:kslabo51:20200310210611p:plain

 

10)有効でないユーザーはログインできないようにする

f:id:kslabo51:20200310212410p:plain

 

11)アカウント有効化の統合テスト

f:id:kslabo51:20200310212642p:plain

f:id:kslabo51:20200310212652p:plain

 

12)リファクタリング

①Userモデルにユーザー有効化メソッドを追加

・アカウントを有効にするactivateメソッド

・有効化用のメールを送るsend_activation_emailメソッド

f:id:kslabo51:20200310213520p:plain

ユーザーモデル内に記述しているためuserという記法を用いない(self or なしでよい)

 

②ユーザーモデルオブジェクトからメールを送信する

f:id:kslabo51:20200310213842p:plain

※①で生成したsend_activation_emailメソッドを呼び出す

 

③ユーザーモデルオブジェクト経由でアカウントを有効化

f:id:kslabo51:20200310214052p:plain

※①で生成したactivateメソッドを呼び出す

 

④indexページとshowページでは有効化されたユーザーのみを表示するように設定

f:id:kslabo51:20200310214636p:plain

 

13)HerokuアドオンSendGrid

本番環境からのメール送信はSendGridを使用する

①アドオンをアプリケーションに追加

$ heroku addons:create sendgrid:starter

 

Railsのproduction環境でsendGridを使う設定をする

f:id:kslabo51:20200310220509p:plain

 

環境変数を設定

SendGridの場合環境変数はアドオンが自動的に設定してくれる。

それらを表示して確認したいときには下記のコマンド

$ heroku config:get SENDGRID_USERNAME

$ heroku config:get SENDGRID_PASSWORD

 

以上で終了(^^)/

 

参考にさせていただいたサイト

第11章 アカウントの有効化 - Railsチュートリアル

Rails6 のちょい足しな新機能を試す61(ActionMailer template_name編) - Qiita