0
0

More than 1 year has passed since last update.

railsチュートリアル第12章 新しいパスワードの設定 createアクションでパスワード再設定

Posted at

新しいパスワードの設定

攻撃者からアカウントを盗まれないようにするため
マイグレーションに図 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>

演習

1.
リスト 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

メイラー

メールは、メールサーバーを介して送受信される仕組みで、データをサーバーに出し入れする仲介役がメーラーです。

演習

1.
試しに有効なメールアドレスをフォームから送信してみましょう(図 12.6)。どんなエラーメッセージが表示されたでしょうか?

ArgumentError in PasswordResetsController#create
wrong number of arguments (given 1, expected 0)

引数が一個来ている 来ない方がいいらしい。

2.
コンソールに移り、先ほどの演習課題で送信した結果、(エラーと表示されてはいるものの)該当するuserオブジェクトにはreset_digestとreset_sent_atがあることを確認してみましょう。また、それぞれの値はどのようになっていますか?

["reset_digest", "$2a$12$******************e"]
"reset_sent_at", "2021-10-20 02:39:36.478649"]

と書かれてあった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0