rails как проверить старый пароль перед обновлением нового пароля

#ruby-on-rails

#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 amp;amp; user.authenticate(password)
      if fcm_token.present? amp;amp; 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
  

Комментарии:

1. Как AuthenticateUser вписывается в картину? Он нигде не используется (что мы видим)

Ответ №1:

has_secure_password предоставляет authenticate метод проверки правильности пароля, вы можете:

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

Комментарии:

1. и нужно добавить:old_password в параметры и в модель user.rb attr_accessor: :old_password

Ответ №2:

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