我怎样才能使一个setter方法的ActiveRecord设置之前,对数据进行加密?

Eth*_*han 2 ruby reflection metaprogramming ruby-on-rails

我想实现一个User名为DB列的Rails 模型password.我想这样做,当我打电话给...

user_instance.password = 'cleartext'
Run Code Online (Sandbox Code Playgroud)

该方法散列明文把它放在像这样的实例之前:

Digest::SHA1.hexdigest(cleartext)
Run Code Online (Sandbox Code Playgroud)

我尝试过使用回调,但问题是每次保存用户时都会哈希,即使pw没有更新.因此,它被散列和重复了无数遍.

我尝试重新定义password=方法......

alias password= old_password=
def password=(cleartext)
  old_password=(Digest::SHA1.hexdigest(cleartext))
end
Run Code Online (Sandbox Code Playgroud)

但得到一个错误说不password=存在.

Mat*_*ish 8

仅供参考,您可能需要查看restful_authentication插件,因为它会为您执行此操作.为什么要自己动手?

acts_as_authenticated的方式是:

  1. 数据库/模型有一个名为"encrypted_pa​​ssword"的列
  2. 创建一个名为password的虚拟属性
  3. 密码未填充在查找(..)上,因此如果密码为空,请不要加密
  4. 如果密码是非空白的,则表示用户输入了密码,因此请继续加密并填写encrypted_pa​​ssword

代码片段(从我的用户类中随机复制粘贴,所以不要盲目地粘贴它):

require 'digest/sha1'
class User < ActiveRecord::Base

  # stuff

  # callback
  before_save   :encrypt_password
  attr_accessor :password

  # methods
    def encrypt_password
      return if password.blank?
      salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
      crypted_password = Digest::SHA1.hexdigest("--#{salt}--#{self.password}--")
    end
Run Code Online (Sandbox Code Playgroud)