RailsのgemのSorceryでパスワードのリセット機能を実装してみます。ほぼ公式ドキュメントのコピペで実装できてしまいます。
reset passwordモジュールのインストールとメーラーの設定
まず、UserMailerという名前でパスワードリセットメール用のMailerを作成します。
rails g mailer UserMailer reset_password_email
そして、reset_passwordのモジュールをインストールしてrails db:migrate。
rails g sorcery:install reset_password --migrations
sorcery.rbでreset password用のmailerを指定します。
Rails.application.config.sorcery.configure do |config| config.user_config do |user| user.reset_password_mailer = UserMailer end config.user_class = "User" end
そのuser_mailer.rbに、メールの基本設定を行います。mailerにはメール内に表示させる情報やメールの送信先を設定します。
def reset_password_email(user) @user = User.find(user.id) @url = edit_password_reset_url(@user.reset_password_token) mail(:to => user.email, :subject => "Reset your password") end
メール本文作成
パスワードリセットメールの本文です。
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!
HTMLメールもありますので、そちらも必要に応じて作成します。
パスワードリセットの機能実装
rails g controller PasswordResetsでパスワードをリセットするアクションを実装していきます。公式ドキュメントの内容そのままコピペしましたが、普通に動きます。。。
class PasswordResetsController < ApplicationController skip_before_filter :require_login def new end def create @user = User.find_by_email(params[:email]) if @user @user.deliver_reset_password_instructions! else return redirect_to(new_password_reset_path, :notice => 'This email is not correct') end return redirect_to(root_path, :notice => 'Instructions have been sent to your email.') end def edit @token = params[:id] @user = User.load_from_reset_password_token(params[:id]) if @user.blank? not_authenticated return end end def update @token = params[:id] @user = User.load_from_reset_password_token(params[:id]) if @user.blank? not_authenticated return end @user.crypted_password = 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
作成したアクションを呼び出すルーティングをroutes.rbに設定しておきます。
resources :password_resets
パスワードの編集画面とパスワードリセット申請画面の作成
パスワードのリセットの再発行画面を実装します。このフォームから申請したら、パスワード変更リクエストメールがユーザーに飛びます。
app/views/password_resets/new.html.erb
<%= form_tag password_resets_path, method: :post do %> <div> <%= label_tag :email %> <%= text_field_tag :email, "" %> </div> <%= submit_tag "パスワードリセットを申請する" %> <% end %>
ちなみに、パスワードのリセットを申請した後に、rails cで対象ユーザーを呼び出してみると、下記のようにtokenが発行されていることがわかります。
reset_password_token: "*************************"
最後にパスワードの編集画面を作成します。パスワード編集画面のURLは/password_resets/:id/editという形式ですが、:idのところに先程のtokenが入ります。
app/views/password_resets/edit.html.erb
<%= form_for @user, :url => password_reset_path(@token), :html => {:method => :put} do |f| %> <div> <%= f.label :メールアドレス %><br /> <%= @user.email %> </div> <div> <%= f.label :パスワード %><br /> <%= f.password_field :password %> </div> <div> <%= f.label :パスワード(確認) %><br /> <%= f.password_field :password_confirmation %> </div> <%= f.submit "パスワードリセット" %> <% end %>
公式ドキュメントのほぼコピペで簡単にパスワード変更が実装できてしまいました。
参考:Reset password · NoamB/sorcery Wiki
Ruby on Railsをこれから本格的に勉強したい人は「エンジニアになるための600時間のプログラミング学習に耐え抜くコツ」という記事がおすすめです。