module GlobalID::Identification
Mix ‘GlobalID::Identification` into any model with a `#find(id)` class method. Support is automatically included in Active Record.
class Person include ActiveModel::Model include GlobalID::Identification attr_accessor :id def self.find(id) new id: id end def ==(other) id == other.try(:id) end end person_gid = Person.find(1).to_global_id # => #<GlobalID ... person_gid.uri # => #<URI ... person_gid.to_s # => "gid://app/Person/1" GlobalID::Locator.locate person_gid # => #<Person:0x007fae94bf6298 @id="1">
Public Instance Methods
Source
# File lib/global_id/identification.rb, line 46 def to_gid_param(options = {}) to_global_id(options).to_param end
Returns the Global ID parameter of the model.
model = Person.new id: 1 model.to_gid_param # => ""Z2lkOi8vYm9yZGZvbGlvL1BlcnNvbi8x"
Source
# File lib/global_id/identification.rb, line 37 def to_global_id(options = {}) GlobalID.create(self, options) end
Returns the Global ID of the model.
model = Person.new id: 1 global_id = model.to_global_id global_id.modal_class # => Person global_id.modal_id # => "1" global_id.to_param # => "Z2lkOi8vYm9yZGZvbGlvL1BlcnNvbi8x"
Source
# File lib/global_id/identification.rb, line 116 def to_sgid_param(options = {}) to_signed_global_id(options).to_param end
Returns the Signed Global ID parameter.
model = Person.new id: 1 model.to_sgid_param # => "BAh7CEkiCGdpZAY6BkVUSSIiZ2..."
Source
# File lib/global_id/identification.rb, line 107 def to_signed_global_id(options = {}) SignedGlobalID.create(self, options) end
Returns the Signed Global ID of the model. Signed Global IDs ensure that the data hasn’t been tampered with.
model = Person.new id: 1 signed_global_id = model.to_signed_global_id signed_global_id.modal_class # => Person signed_global_id.modal_id # => "1" signed_global_id.to_param # => "BAh7CEkiCGdpZAY6BkVUSSIiZ2..."
Expiration¶ ↑
Signed Global IDs can expire some time in the future. This is useful if there’s a resource people shouldn’t have indefinite access to, like a share link.
expiring_sgid = Document.find(5).to_sgid(expires_in: 2.hours, for: 'sharing') # => #<SignedGlobalID:0x008fde45df8937 ...> # Within 2 hours... GlobalID::Locator.locate_signed(expiring_sgid.to_s, for: 'sharing') # => #<Document:0x007fae94bf6298 @id="5"> # More than 2 hours later... GlobalID::Locator.locate_signed(expiring_sgid.to_s, for: 'sharing') # => nil
In Rails, an auto-expiry of 1 month is set by default.
You need to explicitly pass ‘expires_in: nil` to generate a permanent SGID that will not expire,
never_expiring_sgid = Document.find(5).to_sgid(expires_in: nil) # => #<SignedGlobalID:0x008fde45df8937 ...> # Any time later... GlobalID::Locator.locate_signed never_expiring_sgid # => #<Document:0x007fae94bf6298 @id="5">
It’s also possible to pass a specific expiry time
explicit_expiring_sgid = SecretAgentMessage.find(5).to_sgid(expires_at: Time.now.advance(hours: 1)) # => #<SignedGlobalID:0x008fde45df8937 ...> # 1 hour later... GlobalID::Locator.locate_signed explicit_expiring_sgid.to_s # => nil
Note that an explicit ‘:expires_at` takes precedence over a relative `:expires_in`.
Purpose¶ ↑
You can even bump the security up some more by explaining what purpose a Signed Global ID is for. In this way evildoers can’t reuse a sign-up form’s SGID on the login page. For example.
signup_person_sgid = Person.find(1).to_sgid(for: 'signup_form') # => #<SignedGlobalID:0x007fea1984b520 GlobalID::Locator.locate_signed(signup_person_sgid.to_s, for: 'signup_form') => #<Person:0x007fae94bf6298 @id="1">