LoginSignup
26
29

More than 5 years have passed since last update.

devise 新規登録時にパスワードリセットメールを送信したいのでやってみた

Posted at

システム管理者のみが新規登録できる状態を想定してます。ログイン画面で新規登録できることは想定していませんので、あしからず。
システム管理者が新規登録した際に、登録したユーザーにパスリセットのメールを送りたい!
なにせ、システム管理者から通知するのは面倒、メール文面にパスワードを載せるのはセキュリティ上よくない。
なので、通知してリンクから直接パスワードを変更してもらうようにする。

ActionMailerの設定

app/controller/application_controller.rbに記載します。

app/controller/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :set_host

  def set_host
    Rails.application.routes.default_url_options[:host] = request.host_with_port
  end
end

パスリセットメールを送る際にHelperを通るようで、ActionView::Template::Error (Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true)のエラーが出ていたので入れてます。

リセットメールテンプレートのパス設定

テンプレートはこのファイルになります -> app/views/devise/mailer/reset_password_instructions.html.erb

app/views/devise/mailer/reset_password_instructions.html.erb
<p>Hello <%= @resource.email %>!</p>

<p>Someone has requested a link to change your password. You can do this through the link below.</p>

<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>

<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>

デフォルトはこの状態。
edit_password_urlを作成しているルートにあわせてください。僕の場合は edit_user_password_urlにしました\(^o^)/

新規登録時にメール送る

deviseの登録はここ -> app/controllers/users/registrations_controller.rb

app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: :create
  prepend_before_action :require_no_authentication, only: :cancel
  prepend_before_action :authenticate_scope!, only: %i[new create]
  prepend_before_action :set_minimum_password_length, only: :new

  # GET /resource/sign_up
  def new
    super
  end

  # POST /resource
  def create
    build_resource(sign_up_params)
    resource.save
    yield resource if block_given?
    if resource.persisted?
      if resource.active_for_authentication?
        set_flash_message! :success, :signed_up
        sign_up(resource_name, current_user)

        # 登録したアカウントにパスワードリセットメール送信
        self.resource = resource_class.send_reset_password_instructions(resource_params)

        redirect_to admins_path
      else
        set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
        expire_data_after_sign_in!
        respond_with resource, location: after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords resource
      set_minimum_password_length
      respond_with resource
    end
  end



devise元のregistrations_controller.rb/createアクションをオーバーライドしています。
あと、なんかいろいろ設定もしていますのでデフォルトとはちょっと違います。
sign_up(resource_name, current_user)は登録したユーザーでログインし直さないように変更を加えてます。
その下!
self.resource = resource_class.send_reset_password_instructions(resource_params)
を追記してください。
これでreset_password_tokenが作成されます。
edit_password_path(@resource, reset_password_token: @token)(僕の場合はedit_user_password_path)へリダイレクトできるようになります。

リセット画面

app/views/devise/passwords/edit.html.erb
<h2>Change your password</h2>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
  <%= devise_error_messages! %>
  <%= f.hidden_field :reset_password_token %>

  <div class="field">
    <%= f.label :password, "New password" %><br />
    <% if @minimum_password_length %>
      <em>(<%= @minimum_password_length %> characters minimum)</em><br />
    <% end %>
    <%= f.password_field :password, autofocus: true, autocomplete: "off" %>
  </div>

  <div class="field">
    <%= f.label :password_confirmation, "Confirm new password" %><br />
    <%= f.password_field :password_confirmation, autocomplete: "off" %>
  </div>

  <div class="actions">
    <%= f.submit "Change my password" %>
  </div>
<% end %>

<%= render "devise/shared/links" %>

自分のお好きなように文言やスタイルを変更するだけ!(上はデフォ)

最後に

直接パスワード変更画面にリダイレクトしても無理です。
そこで何が必要だったかというとreset_password_token
edit_password_pathにユーザー情報と作成されたreset_password_tokenを渡さないといけないということでした。
これに気づくのにかなり時間がかかった。。。
同じようなことをしたい人の助力となれますよーに。

あとでブログにかこう。

26
29
3

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
26
29