覆盖欧姆模型的属性

时间:2014-08-13 14:10:02

标签: ruby redis sinatra ohm

我遇到一个非常奇怪的问题,欧姆我无法跟踪和解决。 欧姆版本是2.0.1。

这是我的代码:

class User < Ohm::Model
  attribute :username
  attribute :password

  index :username

  def password= string
    @attributes[:password] = BCrypt::Password.create(string) # Tried self.password = BCrypt::whatever too
  end
end

[15] pry(main)> User.find(username: 'test').first.password
=> "$2a$10$j1.s4hmuyCm8RffaEvB8IejaYOiZXWXId1Ccf8S0K3uXduxmMzyUq"
[16] pry(main)> User.find(username: 'test').first.password
=> "$2a$10$/0UzWtVsF.xczf4.UUqrP.PqYHxKs8fkIWKHlVVQVUNPFubzmuCwO"
[17] pry(main)> User.find(username: 'test').first.password
=> "$2a$10$ajlc3BYMOFXYDmy1a112ieXhMm39KoR1wPdPMp4WwEnxb2E35ypvC"
[18] pry(main)> User.find(username: 'test').first.password
=> "$2a$10$TlW87Gpd4RKpPutWzkePqeQiGri2ah.txDda4o6Lki7Sk1vayY9Fm"

基本上我可以设置密码并使用BCrypt对其进行加密,但由于某些原因我每次调用属性时密码都不同。 我不知道这里发生了什么,有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

当Ohm从数据库加载属性时,它不会分配它 到@attributes直接。相反,它使用访问器来允许 任何类型的铸造。在你的情况下,正在发生的是每个 时间Ohm从Redis加载密码字段,它再次处理它 与BCrypt。你可以check the code in question

我通常做的有点不同:我定义了一个属性 在欧姆crypted_password,然后在模型中我定义了一个方法 password=,它接受​​一个字符串并生成加密版本, 然后将其存储在crypted_password属性中。我用的是宝石 叫做Shield,here's the relevant code

你可以做类似于Shield的事情,并使用BCrypt 代替。你必须定义一个属性crypted_password,然后一个 名为password=的方法与您的方法略有不同 目前有:

class User < Ohm::Model
  attribute :username
  attribute :crypted_password

  index :username

  def password= string
    self.crypted_password = BCrypt::Password.create(string)
  end
end

这应该有用,你必须使用crypted_password 验证用户。