新しいパスワードの設定
攻撃者からアカウントを盗まれないようにするため
マイグレーションに図 12.5の属性を追加します
ubuntu:~/environment/sample_app (password-reset) $ rails generate migration add_reset_to_users reset_digest:string reset_sent_at:datetime
Running via Spring preloader in process 7187
invoke active_record
create db/migrate/20211019130931_add_reset_to_users.rb
新しいパスワード再設定画面ビュー
app/views/password_resets/new.html.erb
<% provide(:title, "Forgot password") %>
<h1>Forgot password</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(url: password_resets_path, scope: :password_reset,
local: true) do |f| %>
<!--form_withとは、railsで情報を送信するためのヘルパーメソッド-->
<!--簡単に入力フォームに必要なHTMLを作成することができます-->
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
演習
リスト 12.4のform_withメソッドで、@password_resetではなく:password_resetを使っている理由を考えてみましょう。
わからなかった。
調べてみると
シンボルを使うとよりシンプルなformタグが生成され、オブジェクトを渡すとそのオブジェクトに寄って良しなに出し分けてくれる。
と書いてあった。
何がシンプルなのかわからない。
createアクションでパスワード再設定
パスワード再設定用トークンと送信時のタイムスタンプでデータベースの属性を更新する必要があります。
パスワード再設定用のcreateアクション
app/controllers/password_resets_controller.rb
class PasswordResetsController < ApplicationController
def new
end
def create
@user = User.find_by(email: params[:password_reset][:email].downcase)
# メールアドレスをキーとしてユーザーをデータベースから見つける
if @user
@user.create_reset_digest
# パスワード再設定用トークンを更新
@user.send_password_reset_email
# 送信時のタイムスタンプでデータベースの属性を更新
flash[:info] = "Email sent with password reset instructions"
redirect_to root_url
else
flash.now[:danger] = "Email address not found"
render 'new'
end
end
def edit
end
end
Userモデルにパスワード再設定用メソッドを追加する
app/models/user.rb
class User < ApplicationRecord
.
.
.
# パスワード再設定の属性を設定する
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token))
update_attribute(:reset_sent_at, Time.zone.now)
end
# パスワード再設定のメールを送信する
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
private
.
.
.
end
メイラー
メールは、メールサーバーを介して送受信される仕組みで、データをサーバーに出し入れする仲介役がメーラーです。
演習
試しに有効なメールアドレスをフォームから送信してみましょう(図 12.6)。どんなエラーメッセージが表示されたでしょうか?
ArgumentError in PasswordResetsController#create
wrong number of arguments (given 1, expected 0)
引数が一個来ている 来ない方がいいらしい。
コンソールに移り、先ほどの演習課題で送信した結果、(エラーと表示されてはいるものの)該当するuserオブジェクトにはreset_digestとreset_sent_atがあることを確認してみましょう。また、それぞれの値はどのようになっていますか?
["reset_digest", "$2a$12$******************e"]
"reset_sent_at", "2021-10-20 02:39:36.478649"]
と書かれてあった。