encrypts в Rails 7....
 
Уведомления
Очистить всё

encrypts в Rails 7.0: как теперь искать клиента по телефону?

4 Сообщения
4 Пользователи
1 Реакции
505 Просмотры
GalinaKorneva
Сообщения: 30
Автор темы
Читает чужие PR бэкенд-разработчица
Присоединился: 4 года назад
[#20]

Попросили шифровать в базе телефоны и email клиентов. Включила encrypts :phone в модели, ключи сделала через bin/rails db:encryption:init, положила в credentials. Шифрует, расшифровывает, а Customer.find_by(phone: params[:phone]) теперь всегда nil. Поддержка ищет по телефону каждый день. Что я упускаю?


3 ответа
kostya.sokurov
Сообщения: 73
Держит прод бэкенд-разработчик, senior
Присоединился: 4 года назад

По умолчанию шифрование недетерминированное: одна и та же строка каждый раз шифруется по-разному, искать по ней нельзя в принципе. Для полей, по которым ищешь, есть deterministic: true:

class Customer < ApplicationRecord
  encrypts :phone, deterministic: true
  encrypts :email, deterministic: true, downcase: true
  encrypts :comment
end

Customer.find_by(phone: params[:phone]) # теперь находит

Цена понятная: одинаковые телефоны дают одинаковый шифротекст, по базе видно, что у двух клиентов один номер. Для телефона и email обычно приемлемо, для свободного текста нет, его оставь как есть.

Ещё две вещи. Номер нормализуй до шифрования, иначе «+7 911» и «8911» станут разными строками и поиск снова сломается. И колонку сделай пошире, шифротекст заметно длиннее исходного, в varchar(20) не влезет. Уже зашифрованные записи после смены на deterministic придётся перешифровать через find_each и encrypt.


Ответ
katrin47
Сообщения: 4
Пишет в irb бэкенд-разработчица
Присоединился: 3 года назад

LIKE по зашифрованному полю не работает даже с deterministic. Ищут по последним цифрам, значит, хвост номера отдельной колонкой


Ответ
Улугбек Макаров
Сообщения: 5
Пишет в irb разработчик
Присоединился: 4 года назад

Нормализовать пока можно в before_validation. В main уже лежит normalizes, обещают в 7.1, будет одной строкой


Ответ