【问题标题】:Rails 3.1 Qeurying the database encrypted with attr_encrypted gem (where clause on encrypted fields)Rails 3.1 查询使用 attr_encrypted gem 加密的数据库(加密字段上的 where 子句)
【发布时间】:2026-01-15 07:15:01
【问题描述】:

我已经使用 attr_encrypted gem 加密了表中的一个字段。现在我想查询该特定字段,并将其与我从表单中检索的值进行比较。我该怎么做?

编辑:我需要查询一些加密字段。例如:搜索 encrypted_email、encrypted_name 等(在 where 子句中使用 OR 条件)

【问题讨论】:

    标签: mysql ruby-on-rails ruby-on-rails-3


    【解决方案1】:

    attr_encrypted拦截find_by方法,所以你应该可以这样做:

    class User < ActiveRecord::Base
      attr_encrypted :email, :key => 'a secret key'
      attr_encrypted :password, :key => 'some other secret key'
    end
    
    User.find_by_email_and_password('test@example.com', 'testing')
    

    这里改写为

    User.find_by_encrypted_email_and_encrypted_password('ENCRYPTED EMAIL', 'ENCRYPTED PASSWORD')
    

    【讨论】:

    • 如果我想说我想通过电子邮件或年龄或姓名查找并且所有 3 个都加密了怎么办?
    • 你熟悉ActiveRecord中dynamic finders的概念吗?
    • 是的,我很熟悉它,但我没有将它用于“或”条件。我想它只能用于“和”。如果我错了,请纠正我。
    • 我认为你是对的。在这种情况下,您可以在客户端进行。为每个查询提取 1 条记录并选择其中的第一个。
    • 这会导致数据库调用过多。现在我正在将整个表加载到内存中并操作数据。我想要更高效的东西!!
    【解决方案2】:
    class User < ActiveRecord::Base 
      attr_encrypted :email, :key => 'a secret key'
    end
    

    如果您想编写查询来检索电子邮件为“abc@xyz.com”的用户,那么您可以这样做

    User.where(encrypted_email: User.encrypt_email('abc@xyz.com'))
    

    User.scoped_by_email('abc@xyz.com') # works only for dynamic scope methods
    

    【讨论】:

    • 如果您使用per_attribute_iv_and_salt 模式,使用带有encrypt_email 属性方法的where 范围进行搜索是否有效?
    • @richsinn 我没试过那样做。但是你可以试一试:)