实例公共方法
find_signed(signed_id, purpose: nil, on_rotation: nil) 链接
允许您根据一个已签名的 ID 来查找记录,该 ID 是安全的,可以公开而不必担心被篡改。这对于密码重置或电子邮件验证等场景特别有用,您希望已签名的 ID 的持有者能够与底层记录进行交互,但通常仅限于特定时间段内。
您在生成时使用实例方法 signed_id(expires_in: 15.minutes) 来设置已签名 ID 的有效时间。如果在尝试查找已签名 ID 之前时间已过,则该已签名 ID 将不再有效,并将返回 nil。
可以使用 purpose(目的)来进一步限制已签名 ID 的使用。当您有一个通用的基础模型(如 User)时,这很有帮助,它可能拥有用于密码重置或电子邮件验证等多种用途的已签名 ID。生成时设置的 purpose 必须与查找时设置的 purpose 匹配。如果存在不匹配,将再次返回 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
来源: 显示 | 在 GitHub 上
# File activerecord/lib/active_record/signed_id.rb, line 68 def find_signed(signed_id, purpose: nil, on_rotation: nil) raise UnknownPrimaryKey.new(self) if primary_key.nil? options = { on_rotation: on_rotation }.compact if id = signed_id_verifier.verified(signed_id, purpose: combine_signed_id_purposes(purpose), **options) find_by primary_key => id end end
find_signed!(signed_id, purpose: nil, on_rotation: nil) 链接
功能类似于 find_signed,但如果 signed_id 已过期、purpose 不匹配、是用于其他记录,或已被篡改,则会引发 ActiveSupport::MessageVerifier::InvalidSignature 异常。如果有效的已签名 ID 找不到记录,它还会引发 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
来源: 显示 | 在 GitHub 上
# File activerecord/lib/active_record/signed_id.rb, line 89 def find_signed!(signed_id, purpose: nil, on_rotation: nil) options = { on_rotation: on_rotation }.compact if id = signed_id_verifier.verify(signed_id, purpose: combine_signed_id_purposes(purpose), **options) find(id) end end
signed_id_verifier() 链接
来源: 显示 | 在 GitHub 上
# File activerecord/lib/active_record/signed_id.rb, line 96 def signed_id_verifier if signed_id_verifier_secret @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" end ActiveSupport::MessageVerifier.new secret, digest: "SHA256", serializer: JSON, url_safe: true end else return _signed_id_verifier if _signed_id_verifier if ActiveRecord.message_verifiers.nil? raise "You must set ActiveRecord.message_verifiers to use signed IDs" end ActiveRecord.message_verifiers["active_record/signed_id"] end end
signed_id_verifier=(verifier) 链接
允许您传递一个自定义的 verifier(验证器)来用于已签名 ID。这还允许您为不同的类使用不同的 verifier。如果您需要轮换密钥,这也会很有帮助,因为您可以提前为您的自定义 verifier 做好准备。有关详细信息,请参阅 ActiveSupport::MessageVerifier。
来源: 显示 | 在 GitHub 上
# File activerecord/lib/active_record/signed_id.rb, line 122 def signed_id_verifier=(verifier) if signed_id_verifier_secret @signed_id_verifier = verifier else self._signed_id_verifier = verifier end end