RailsアプリでSorceryでパスワードリセット機能を実装する

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時間のプログラミング学習に耐え抜くコツ」という記事がおすすめです。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする