Rails中Lockbox与Blind Index加密字段无法访问问题排查
问题:删除明文email列后无法访问加密字段
email 环境:
- Lockbox v1.3.3、Blind Index v2.3.2(无法升级)
- Rails 6.0.3.2、Ruby 2.6.9
操作流程:
- 执行初始迁移添加
email_ciphertext和email_bidx列 - 运行
Lockbox.migrate(User)完成现有数据加密 - 删除明文
email列后,调用User.last.email时报错:
undefined method `email' for #<User:0x0000000125f46340>
用户模型代码:
... has_encrypted :email, migrating: true blind_index :email, migrating: true # 删除列后移除该行也无变化,仍无法访问email self.ignored_columns = ["email"] ...
初始迁移代码:
class AddEncryptionToPiiFields < ActiveRecord::Migration[6.0] def change # 用户加密字段 add_column :users, :email_ciphertext, :text # 用户盲索引列及索引 add_column :users, :email_bidx, :string add_index :users, :email_bidx, unique: true end end
删除明文列的迁移代码:
class DropNonEncryptedFields < ActiveRecord::Migration[6.0] def change remove_column :users, :email end end
当前状态:数据库中email_ciphertext和email_bidx列存在,可正常访问User.last.email_ciphertext,但无法访问email属性。
解决方案
1. 移除migrating: true参数
Lockbox的migrating: true是明文列存在时的过渡兼容配置,它会优先读取明文列的值,同时写入加密列。当明文列已删除后,该参数会干扰Lockbox生成email属性的访问器方法。
修改用户模型代码:
has_encrypted :email blind_index :email
2. 移除ignored_columns配置
明文列已删除,self.ignored_columns = ["email"]无意义,移除后避免干扰ActiveRecord的属性映射逻辑。
3. 重启Rails服务器
修改模型配置后,必须重启服务器才能让新配置生效。
原理说明
在Lockbox v1.x版本中,migrating: true会让gem处于兼容模式,此时若明文列被删除,gem无法正确触发加密字段的访问器生成逻辑,导致email方法不存在。移除该参数后,Lockbox会正常为email生成对应的getter/setter方法,从email_ciphertext中解密获取值。
内容的提问来源于stack exchange,提问作者sckdd
相关产品推荐
相关产品推荐

