初心者ということもあり、用語についても調べてアウトプットしていきます!
初心者の同志の方の勉強の一助になれれば幸いです♪
それでは頑張っていきましょう
パスワードリセット機能の実装
Sorceryのreset_passwordモジュールを使って実装していきます。
github.com
$rails g sorcery:install reset_password --only-submodules
実行するとmigrationファイルが作成されます。
#migrationファイル
class SorceryResetPassword < ActiveRecord::Migration
def change
add_column :users, :reset_password_token, :string, default: nil
add_column :users, :reset_password_token_expires_at, :datetime, default: nil
add_column :users, :reset_password_email_sent_at, :datetime, default: nil
end
end
$bundle exec rails db:migrate
バリデーションの追加
#user.rb
validates :reset_password_token, uniqueness: true, allow_nil: true
・uniquenessは属性の値が一意であることを検証。
・allow_nilは、対象の値がnilの場合にバリデーションをスキップ。(reset_password_tokenはnilになるため、allow_nil: trueがないとユニーク制約に引っかかる)
Malerの作成
$ rails g mailer UserMailer reset_password_email
# config/initializers/sorcery.rb
Rails.application.config.sorcery.submodules = [:reset_password]
Rails.application.config.sorcery.configure do |config|
config.user_config do |user|
user.reset_password_mailer = UserMailer
end
end
・reset_passwordをサブモジュールに追加
・UserMailerを定義
#app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
default from: 'test@test.com'
def reset_password_email(user)
@user = User.find(user.id)
@url = edit_password_reset_url(@user.reset_password_token)
mail(to: user.email, subject: 'パスワードリセット')
end
end
・送信元のメールアドレスを指定
・@urlでメールに記載するパスワードリセット用URLを定義
・宛先、件名を指定
Malerのビュー
# app/views/user_mailer/reset_password_email.text.erb
Hello, <%= @user.email %>
===============================================
You have requested to reset your password.
To choose a new password, just follow this link: <%= @url %>.
Have a great day!
app/views/layouts/mailer.html.erbも一緒にファイルが作成されているはず、
全てのクライアントがHTMLメールを受信出来る訳では無いので、両方作成し送信します。
コントローラー作成
$ rails g controller PasswordResets new create edit update
# app/controllers/password_resets_controller.rb
class PasswordResetsController < ApplicationController
skip_before_action :require_login
def new; end
#パスワードリセット対象のメールアドレスを申請して、リセットの対象を作成する
def create
@user = User.find_by_email(params[:email])
# ユーザーのメールアドレスがDBに存在すれば、パスワードをリセットするURL(ランダムトークン・有効期限を含む)をメールでユーザーに送信する
@user.deliver_reset_password_instructions! if @user
# 存在しないメールアドレスだとしてもこのメッセージを出力させる
redirect_to(root_path, :notice => 'Instructions have been sent to your email.')
end
#パスワードリセット用のメールのURLをクリックして、新しいパスワードを入力する
def edit
@token = params[:id]
@user = User.load_from_reset_password_token(params[:id])
if @user.blank?
not_authenticated
return
end
end
#パスワードリセット(edit)ページにて、『更新する』ボタンでパスワードを変更する
def update
@token = params[:id]
@user = User.load_from_reset_password_token(params[:id])
if @user.blank?
not_authenticated
return
end
#パスワード確認の検証を機能させる
@user.password_confirmation = params[:user][:password_confirmation]
#一時トークンをクリアし、パスワードを更新する
if @user.change_password(params[:user][:password])
redirect_to(root_path, :notice => 'Password was successfully updated.')
else
render :action => "edit"
end
end
end
letter_opener_webでメールを確認
gem 'letter_opener_web'
をGemfileに追加することで、メールが実際に送受信されるかWebで見ることができるようになります。
bundle install
#config/routes.rb
mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?
を追加します。
#config/environments/development.rb
Rails.application.configure do
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: 'localhost:3000' }
config.action_mailer.delivery_method = :letter_opener_web
end
設定できたので下記のURLから確認します。
http://localhost:3000/letter_opener
メールは送られているでしょうか?
本日はパスワードリセット機能を実装しました!