当原始值为空字符串时,防止“ attr_encrypted”和“ blind_index”创建加密字段

时间:2018-11-08 15:33:31

标签: ruby-on-rails postgresql encryption

我正在使用attr_encryptedblind_index宝石来安全地保存和搜索敏感数据。

宝石文件:

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_ivencrypted_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: '')可以做!

1 个答案:

答案 0 :(得分:3)

这两种宝石都只产生SELECT * FROM job as J LEFT JOIN interview as I ON J.uni = I.uniid WHERE J.id = I.jobid值的NULL,您可以在控制器中对其进行修补:

nil

或通过覆盖setter来使模型将空字符串转换为params[:user][:email] = nil if params[:user][:email].empty? @user = User.new(user_params) ...

nil