我有一个名为Contact的模型,它包含用户的手机号码和电子邮件等敏感信息。因此,我使用的是gem attr_encrypted,列mobile_number和email是默认加密和存储的。
在检索记录时,默认情况下会解密mobile_number和电子邮件,这就是gem的行为。
Contact.first.email => decypted email is returned
我将加密密钥和版本存储在另一个名为client_encryption的表中。
因此,每当我调用Contact.first.email时,都会触发两个查询,一个用于获取Contact,另一个用于提取所需的加密密钥。
我目前正在为我拥有的所有联系人(超过100万(生成CSV。因此,在CSV生成中,每次我调用contact.email时,获取加密密钥的查询也会被触发(因此,同一查询会被触发100万次(。
如何避免运行加密密钥获取查询?我可以手动解密电子邮件,但不确定如何解密,因为加密是由gem完成的。
我们可以简单地使用解密方法的优势。
Contact.decrypt_#{encrypted_column_name}(encrypted_value, key: encryption_key)
就我而言,它必须是
Contact.decrypt_email(encrypted_email, key: encryption_key)
所以每次在我的循环中,而不是调用
contact.email (which will call query to fetch encryption key), I will simply call decrypt method with the encryption_key that is already cached.