модуль ActiveRecord::SignedId::ClassMethods
Открытые методы экземпляров
# File activerecord/lib/active_record/signed_id.rb, line 52
def find_signed(signed_id, purpose: nil)
raise UnknownPrimaryKey.new(self) if primary_key.nil?
if id = signed_id_verifier.verified(signed_id, purpose: combine_signed_id_purposes(purpose))
find_by primary_key => id
end
end Позволяет найти запись по подписанному идентификатору, который безопасно использовать в публичном доступе без риска подделки. Это особенно полезно для сброса пароля или проверки адреса электронной почты, где владелец подписанного идентификатора может взаимодействовать с базовой записью, но обычно только в определенный период времени.
Период действия подписанного идентификатора устанавливается при его генерации с помощью метода экземпляра signed_id(expires_in: 15.minutes). Если период истек до попытки найти запись по подписанному идентификатору, подписанный идентификатор больше не будет действительным, и будет возвращено значение nil.
Можно дополнительно ограничить использование подписанного идентификатора с помощью цели. Это полезно, когда у вас есть базовая модель (например, пользователь), которая может иметь подписанные идентификаторы для нескольких целей (например, сброса пароля или проверки адреса электронной почты). Цель, установленная при генерации, должна совпадать с целью, заданной при поиске. Если есть несоответствие, снова будет возвращено значение nil.
Примеры
signed_id = User.first.signed_id expires_in: 15.minutes, purpose: :password_reset User.find_signed signed_id # => nil, since the purpose does not match travel 16.minutes User.find_signed signed_id, purpose: :password_reset # => nil, since the signed id has expired travel_back User.find_signed signed_id, purpose: :password_reset # => User.first
# File activerecord/lib/active_record/signed_id.rb, line 72
def find_signed!(signed_id, purpose: nil)
if id = signed_id_verifier.verify(signed_id, purpose: combine_signed_id_purposes(purpose))
find(id)
end
end Работает как find_signed, но вызовет исключение ActiveSupport::MessageVerifier::InvalidSignature, если подписанный идентификатор истек, цель не совпадает, идентификатор относится к другой записи или был изменён. Также будет выброшено исключение ActiveRecord::RecordNotFound, если по действительному подписанному идентификатору не найдена запись.
Примеры
User.find_signed! "bad data" # => ActiveSupport::MessageVerifier::InvalidSignature signed_id = User.first.signed_id User.first.destroy User.find_signed! signed_id # => ActiveRecord::RecordNotFound
# File activerecord/lib/active_record/signed_id.rb, line 81
def signed_id_verifier
@signed_id_verifier ||= begin
secret = signed_id_verifier_secret
secret = secret.call if secret.respond_to?(:call)
if secret.nil?
raise ArgumentError, "You must set ActiveRecord::Base.signed_id_verifier_secret to use signed ids"
else
ActiveSupport::MessageVerifier.new secret, digest: "SHA256", serializer: JSON, url_safe: true
end
end
end Экземпляр верификатора, с помощью которого генерируются и проверяются все подписанные идентификаторы. По умолчанию он инициализируется с помощью класса signed_id_verifier_secret, который в Rails берётся из Rails.application.key_generator. По умолчанию используется SHA256 для дайджеста и JSON для сериализации.
# File activerecord/lib/active_record/signed_id.rb, line 97 def signed_id_verifier=(verifier) @signed_id_verifier = verifier end
Позволяет указать настраиваемый верификатор, используемый для подписанных идентификаторов. Это также позволяет использовать разные верификаторы для разных классов. Это также полезно, если вам нужно вращать ключи, так как вы можете заранее подготовить свой настраиваемый верификатор для этого. Подробнее см. ActiveSupport::MessageVerifier.
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.