Rails如何在更新新密码之前验证旧密码

时间:2019-03-12 10:32:02

标签: ruby-on-rails

我不知道该怎么做。我想在更新旧密码之前检查旧密码。我应该怎么做?我不明白如何将密码转换为password_digest。以及如何检查类似

的内容
if @user.user_params(:old_password) == @user(:password_digest)
  @user.update attributes

但未选中,因为无法检查密码摘要。

我有一个控制器: users_controller.rb

# PATCH/PUT /users/1
def update
  @user.update_attributes!(user_params)
  head :no_content
end

private
def user_params
  PrettyApi.with_nested_attributes(pretty_user_params, :worker)
end

# Only allow a trusted parameter "white list" through.
def pretty_user_params
  params.require(:user).permit(
  :email,
  :first_name,
  :last_name,
  :phone_number,
  :password,
  :password_confirmation,
  roles: [],
  worker: [
    :id,
    :rate,
    :crew_leader,
    :_destroy
  ]
)
end

user.rb

has_secure_password

schema.rb

  create_table "users", force: :cascade do |t|
t.bigint "company_id"
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "roles", default: [], array: true
t.string "reset_token"
t.string "phone_number"
t.datetime "reset_sent_at"
t.index ["company_id"], name: "index_users_on_company_id"
t.index ["email"], name: "index_users_on_email"
t.index ["first_name"], name: "index_users_on_first_name"
t.index ["last_name"], name: "index_users_on_last_name"
end

authenticate_user.rb

class AuthenticateUser
  def initialize(email, password, remember_me=nil, fcm_token=nil, platform=nil)
    @email = email
    @password = password
    @remember_me = remember_me
    @fcm_token = fcm_token
    @platform = platform
  end

  # Service entry point
  def call
    return unless user

    if is_remember_me_active?
      JsonWebToken.encode(encode_fields, 120.days.from_now)
    else
      JsonWebToken.encode(encode_fields)
    end
  end

  private

  attr_reader :email, :password, :remember_me, :fcm_token, :platform

  # verify user credentials
  def user
    user = User.find_by(email: email)
    if user && user.authenticate(password)
      if fcm_token.present? && platform.present?
        firebase_token = FirebaseToken.find_by(user: user, platform: platform)
        if firebase_token.present?
          firebase_token.update(token: fcm_token)
        else
          FirebaseToken.create(
            user: user,
            platform: platform,
            token: fcm_token
         )
        end
      end
      return user
    end
    # raise Authentication error if credentials are invalid
    raise(ExceptionHandler::AuthenticationError, Message.invalid_credentials)
  end

  def encode_fields
    {
      user_id: user.id,
      roles: user.roles
    }
  end

  def is_remember_me_active?
    remember_me.eql?('true')
  end
end

2 个答案:

答案 0 :(得分:1)

has_secure_password提供了authenticate方法来检查密码是否正确,您可以:

if @user.authenticate(params[:old_password])
  @user.update!(...)
else
  # handle incorrect old password
end

答案 1 :(得分:0)

Devise支持valid_password方法来检查给定的密码是否与当前密码匹配。 为了验证旧密码:

@user = User.find_by_email(params[:email])
if @user.valid_password?(params[:old_password])
   @user.password = params[:password]
   @user.password_confirmation = params[:password_confirmation]
   if @user.save!
     render json: "password updated successfully", status: :accepted
   else
     render json: "could not update password", status: :not_acceptable
   end
end