Ответ 1
В вашей модели сделайте следующее:
before_create :randomize_id
...
private
def randomize_id
begin
self.id = SecureRandom.random_number(1_000_000)
end while Model.where(id: self.id).exists?
end
Я пишу приложение rails, которое по своей природе НЕ МОЖЕТЕ требовать от пользователей регистрации, и поэтому не может использовать аутентификацию в качестве обычного средства защиты записей. (Я знаю, я знаю...) Информация пользователя здесь ограничена адресами электронной почты. Поэтому мне нужен способ сделать мои идентификаторы модели непредсказуемыми, чтобы другие идентификаторы не могли быть легко угаданы. (Я знаю, я знаю...)
Я пробовал использовать плагины, такие как uuidtools, для рандомизации идентификаторов, поскольку записи создаются так:
require 'uuidtools'
class Post < ActiveRecord::Base
def before_create()
self.id = OpenSSL::Digest.SHA1.hexdigest(UUID.timestamp_create())
end
end
... Сначала это выглядит хорошо, но забавные вещи случаются. ActiveRecord иногда пытается вставить значение 0 в id, и я получаю такие ошибки, как "не удается найти сообщение с id = 0" и т.д.
У меня закончились идеи. Может ли кто-нибудь помочь? Спасибо.
В вашей модели сделайте следующее:
before_create :randomize_id
...
private
def randomize_id
begin
self.id = SecureRandom.random_number(1_000_000)
end while Model.where(id: self.id).exists?
end
Лучший способ - использовать SecureRandom.uuid
, который генерирует UUID V4 (универсально уникальный идентификатор).
Он практически полностью случайен и уникален (вероятность столкновения - это что-то вроде одного десятка триллионов): https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29
Это должно выполнить задание:
class Post < ActiveRecord::Base
before_create :generate_random_id
private
def generate_random_id
self.id = SecureRandom.uuid
end
end
Или, если вы используете Rails >= 4 и PostgreSQL, вы можете создать его для вас:
create_table :posts, id: :uuid do |t|
...
end
Там есть плагин, который должен делать то, что вы хотите:
http://codesnipers.com/?q=using-uuid-guid-as-primary-key-in-rails
(Все извиняются за цензуры SO за то, что они не вставлялись во всю статью. В моей защите он загружался ссылками и форматированием, для чего потребовалось бы немало усилий для репликации. Не говоря уже о том, что мы будем грабить страницу автора трафика и потенциального дохода.)
Вещь, которая здесь не так, заключается в том, что self.id требует int и OpenSSL:: Digest.SHA1.hexdigest(UUID.timestamp_create()) возвращает строку с нечисловыми символами, которая приведет к значению '0 'фактически хранится в базе данных
Альтернативой является создание маркера или контрольной суммы или что-то другое во втором столбце во время создания записи, и во всех случаях, когда ваши контроллеры запрашивают объект, используйте Model.find_by_id_and_token
.
Вы всегда будете генерировать URL-адреса, содержащие и требующие как идентификатор, так и токен.