我使用attr_encrypted和blind_index Gems来安全地保存和搜索敏感数据。
Gemfile:
gem "attr_encrypted", "~> 3.0.0"
gem "blind_index"模型
attr_encrypted :email, :key => [ENV["DB_ENCRYPTED_KEY"]].pack("H*")
blind_index :email, :key => [ENV["BLIND_INDEX_KEY"]].pack("H*")
validates :email, :uniqueness => true, :allow_blank => true迁移
add_column :users, :encrypted_email, :string
add_column :users, :encrypted_email_iv, :string
add_column :users, :encrypted_email_bidx, :string
add_index :users, :encrypted_email_bidx, :unique => true除了当我试图添加一个电子邮件为空(空字符串)的用户时,它仍然创建encrypted_email_iv和encrypted_email_bidx字段,因此,当我尝试用空电子邮件创建另一个用户时,它会引发一个postgres 'PG::UniqueViolation‘异常。以下是详细的错误:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_customers_on_encrypted_email_bidx" DETAIL: Key (encrypted_email_bidx)=(DuFZwCHck+O9kivr2J64r5Q9MJrGoP5P1U0ikIgyj7c= ) already exists.当我从rails控制台尝试时,我会得到同样的错误,但是如果电子邮件是nil,而不是空字符串,它就可以正常工作。
因此,User.create(name: 'aaa', telephone: '1234-5678')不会创建加密字段,而User.create(name: 'aaa', telephone: '1234-5678', email: '')会创建加密字段!!
发布于 2018-11-08 17:35:30
这两个gems只为nil值生成nil,您可以在控制器中对它们进行修补:
params[:user][:email] = nil if params[:user][:email].empty?
@user = User.new(user_params)
...或者通过重写setter使模型将空字符串转换为nil:
attr_encrypted :email, ...
...
old_setter = instance_method(:email=)
define_method(:email=) do |val|
val = nil if val.blank?
old_setter.bind(self).call(val)
endhttps://stackoverflow.com/questions/53211030
复制相似问题