无需散列两次密码即可更新用户

时间:2014-02-08 12:16:40

标签: sinatra sequel bcrypt-ruby

我的模特:

class User < Sequel::Model
self.raise_on_save_failure = false
plugin :validation_helpers
def validate
    super
    validates_format /@/, :email
    validates_presence [:email, :password]
    validates_unique :email
end

def before_save
    super
    self[:password] = BCrypt::Password.create(self[:password])
end

但是当我更新用户时,我的密码会哈希两次。我知道这是因为before_save挂钩,但我想保持sequel验证(validates_presence)真正的密码,而不是bcrypt哈希的结果(原因BCrypt::Password.create('')是不是空的)

所以我需要以某种方式做下一步:

  1. 检查密码是否已更改
  2. sequel
  3. 验证真实密码
  4. 保存我的密码的bcrypt哈希

2 个答案:

答案 0 :(得分:2)

我认为你应该重新考虑你的工作流程。如果您希望仅在尝试更新数据库时捕获无效输入,为什么不这样做:

post '/update' do
  ...

  if params[:password] == nil || params[:password].empty?
    password = nil
  else
    password = BCrypt::Password.create(params[:password])
  end

  # I have no idea how this line should really look like in your code
  User.find(param[:id]).set(:password, password)

  ...
end

所以基本上,如果没有发送密码字段或为空,请将其设为零。

修改

正如iain在评论中非常清楚地说明的那样:

  

[...]您应该只使用Sequel验证数据库将要或将要保留的数据。真正的密码应该由业务逻辑层验证,这就是这个答案中发生的事情。

答案 1 :(得分:0)

您可以在类方法中检查它:

  if user.password_digest != expected_password
    user = nil
  end