123456789_123456789_123456789_123456789_123456789_

Module: ActiveRecord::SignedId

Relationships & Source Files
Namespace Children
Modules:
Extension / Inclusion / Inheritance Descendants
Included In:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Defined in: activerecord/lib/active_record/signed_id.rb

Class Method Summary

::ActiveSupport::Concern - Extended

class_methods

Define class methods from given block.

included

Evaluate given block in context of base class, so that you can write class macros here.

prepended

Evaluate given block in context of base class, so that you can write class macros here.

append_features, prepend_features

Instance Method Summary

DSL Calls

included

[ GitHub ]


8
9
10
11
12
13
14
# File 'activerecord/lib/active_record/signed_id.rb', line 8

included do
  ##
  # :singleton-method:
  # Set the secret used for the signed id verifier instance when using Active Record outside of \Rails.
  # Within \Rails, this is automatically set using the \Rails application key generator.
  class_attribute :signed_id_verifier_secret, instance_writer: false
end

Instance Method Details

#signed_id(expires_in: nil, expires_at: nil, purpose: nil)

Returns a signed id that’s generated using a preconfigured ::ActiveSupport::MessageVerifier instance.

This signed id is tamper proof, so it’s safe to send in an email or otherwise share with the outside world. However, as with any message signed with a ::ActiveSupport::MessageVerifier, [the signed id is not encrypted](classes/ActiveSupport/MessageVerifier.html#class-ActiveSupport::MessageVerifier-label-Signing+is+not+encryption). It’s just encoded and protected against tampering.

This means that the ID can be decoded by anyone; however, if tampered with (so to point to a different ID), the cryptographic signature will no longer match, and the signed id will be considered invalid and return nil when passed to find_signed (or raise with find_signed!).

It can furthermore be set to expire (the default is not to expire), and scoped down with a specific purpose. If the expiration date has been exceeded before find_signed is called, the id won’t find the designated record. If a purpose is set, this too must match.

If you accidentally let a signed id out in the wild that you wish to retract sooner than its expiration date (or maybe you forgot to set an expiration date while meaning to!), you can use the purpose to essentially version the signed_id, like so:

user.signed_id purpose: :v2

And you then change your find_signed calls to require this new purpose. Any old signed ids that were not created with the purpose will no longer find the record.

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'activerecord/lib/active_record/signed_id.rb', line 131

def signed_id(expires_in: nil, expires_at: nil, purpose: nil)
  raise ArgumentError, "Cannot get a signed_id for a new record" if new_record?

  self.class.signed_id_verifier.generate id, expires_in: expires_in, expires_at: expires_at, purpose: self.class.combine_signed_id_purposes(purpose)
end