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

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

Rails 6.0でアプリを開発 基本の流れ⑪ パスワードの再設定

今回はパスワードを忘れた場合の再設定用のコードのメモ

f:id:kslabo51:20200312195832j:plain

 実現したいこと

ログインフォームにパスワードを忘れた場合のリンクを置き、クリックするとフォームが表示。メアドを入力し送信するとメールが届く。そのメール内にあるリンクをクリックすると再設定用のフォームが出てきて再設定できる。

 

今回の流れ

 

  1. 再設定用のリクエストを受けるとメアドをキーにしてDBからユーザーを見つける。
  2. メアドがDBにある場合は再設定用トークンとそれに対応するリセットダイジェストを生成。
  3. 再設定用ダイジェストはDBに保存。再設定用トークンはメアドと一緒にユーザーに送信する有効化用のメールのリンクに仕込む。
  4. ユーザーがリンクをクリックしたら、メアドをキーにしてユーザーを探しDB内で保存しておいた再設定用ダイジェストと比較(トークン認証)
  5. 認証に成功したらパスワード変更用のフォームを表示。

 

1)パスワード再設定用のコントローラーの作成

$ rails g controller PasswordResets new edit --no-test-framework

 

・メールを入力するフォームのnewとパスワードを再設定するフォームのeditのビューがいる

・統合テストでカバーしコントローラーの単体テストをしないのでテストを生成しないオプションを渡している

・その他createとupdateが必要

 

2)ルーティングの設定

resourceっでnew、edit、create、updateを設定

f:id:kslabo51:20200311204221p:plain

 

3)パスワード再設定画面へのリンクを追加

ログインフォーム上に設定

f:id:kslabo51:20200311204512p:plain

4)マイグレーションにreset_digestとreset_sent_atを追加

・パスワードの再設定もトークン用の仮想的な属性と対応するダイジェストが必要

・再設定用のリンクはなるべく短時間で期限切れにする

$ rails g migration add_reset_to_users reset_digest:string reset_sent_at:datetime

$ rails db:migrate

 

5)新しいパスワード再設定画面ビュー(メアドを送信するフォーム)

f:id:kslabo51:20200311205447p:plain

 

6)パスワード再設定用のcreateアクションの作成

f:id:kslabo51:20200311205934p:plain

 

7)Userモデルにパスワード再設定用のメソッドを追加

・createアクション内で呼び出しているメソッドを作成

f:id:kslabo51:20200311210505p:plain

 

8)パスワード再設定のリンクをメール送信するメソッドをmailerに記述

f:id:kslabo51:20200311211918p:plain

 

9)パスワード再設定のテンプレ

テキストメール

f:id:kslabo51:20200311211305p:plain

 

htmlメール

f:id:kslabo51:20200311211348p:plain

 

10)パスワード再設定のプレビューメソッドの作成

f:id:kslabo51:20200311211622p:plain

 

11)パスワード再設定用メイラーメソッドのテストを追加

f:id:kslabo51:20200311212402p:plain

 

12)隠しフィールドでメアドを保存

updateアクションで必要となるメアドを保持するため隠しフィールドとしてページ内に保存する。

f:id:kslabo51:20200311214246p:plain

※hidden_field_tag内にメアドを保持

フォームから送信すると情報と一緒に保持されったメアドも送信される

  • hidden_field_tag :email →params[::email]に保存される
  • f.hidden_field :email →params[:user][:email]に保存される

 

13)editアクションとupdateアクションにbeforeコールバックを設定

editアクションが行われる前にユーザーを見つけ正しいユーザーか確認する

f:id:kslabo51:20200311214922p:plain

対応するメソッドをprivate内に

f:id:kslabo51:20200311215028p:plain

14)updateアクションで考慮するケース

  1. パスワードの有効期限が切れていないか
  2. 無効なパスワードは失敗させる(理由も表示する)
  3. 新しいパスワードが空文字になっていないか
  4. 新しいパスワードが正しければ更新する

 

15)updateアクション用のコールバックとメソッドおよびupdateアクションを設定

  • 有効期限をチェックするメソッドをprivate内に設定
  • allow_nilを実装している場合、空文字でも通ってしまうので空文字に引っかかるように明示的にキャッチする →@userオブジェクトにエラーメッセージを追加
  • updateはストロングパラメータを使用する

f:id:kslabo51:20200311215942p:plain

f:id:kslabo51:20200311220034p:plain

updateメソッドの設定

f:id:kslabo51:20200311220130p:plain

 

16)有効期限をチェックするメソッドをUserモデルで定義

f:id:kslabo51:20200311220337p:plain

17)パスワードの再設定を統合テスト

$ rails g integration_test password_resets

 

f:id:kslabo51:20200312194348p:plain

f:id:kslabo51:20200312194401p:plain

f:id:kslabo51:20200312194413p:plain
 

18)パスワードが再設定されたらダイジェストをnilにする

f:id:kslabo51:20200312195029p:plain

 

以上です(^^)/

 

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

第12章 パスワードの再設定 - Railsチュートリアル

update_attribute とupdate_attribtues の違い - LukeSilvia’s diary