我正在使用attr_encrypted
和blind_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_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: '')
可以做!
答案 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