ActiveModel::PasswordReset
is a lightweight password reset model implemented on top of ActiveModel::Model
. It does not require storing any additional information in the database. Resulting token is signed by ActiveSupport::MessageVerifier
class, using secret_key_base
and salt. Token is invalidated when:
- user changed password
- expiration time passed (default: 24 hours)
Add this line to your application's Gemfile:
gem "active_model-password_reset"
And then execute:
$ bundle
Or install it yourself as:
$ gem install active_model-password_reset
The most popular workflow is:
class PasswordResetsController < ApplicationController
def new
@password_reset = ActiveModel::PasswordReset.new
end
def create
@password_reset = ActiveModel::PasswordReset.new(password_reset_params)
if @password_reset.valid?
UserMailer.reset_password(password_reset.email, password_reset.token).deliver
redirect_to root_url, notice: "You will receive an email with instructions."
else
render :new
end
end
private
def password_reset_params
params.require(:active_model_password_reset).permit(:email)
end
end
class PasswordsController < ApplicationController
def edit
# find raises TokenInvalid, TokenExpired, EmailInvalid, PasswordChanged exceptions
@password_reset = ActiveModel::PasswordReset.find(params[:id])
@user = @password_reset.user
rescue ActiveModel::PasswordReset::Error
raise ActiveRecord::RecordNotFound # display 404
end
def update
@password_reset = ActiveModel::PasswordReset.find(params[:id])
@user = @password_reset.user
if @user.update(user_params)
redirect_to root_url, notice: "Password changed successfully, you can now log in."
else
render :edit
end
rescue ActiveModel::PasswordReset::Error
raise ActiveRecord::RecordNotFound # display 404
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
end
If you don't like the default behavior, you can always inherit the session model and override some defaults:
class PasswordReset < ActiveModel::PasswordReset
EXPIRATION_TIME = 1.hour
def email=(email)
@email = email
@user = Admin.find_by(email: email)
end
end
Copyright © 2014 Kuba Kuźma. See LICENSE for details.