globalid icon indicating copy to clipboard operation
globalid copied to clipboard

Consider adding a request-specific expires_at

Open DaanVanVugt opened this issue 1 year ago • 1 comments

This way signed global IDs can be compared even if generated in different places (we get this issue with html select elements, and with ids generated across the app).

Example code to add to ApplicationController:

  before_action :set_sgid_expiry

  # Set a default expiry for SGIDs which means that any ids generated within this request will have the same value
  # and can thus be matched on the frontend
  def set_sgid_expiry
    SignedGlobalID.expires_at 1.week.from_now
  end

Would this be something viable?

DaanVanVugt avatar Nov 10 '23 08:11 DaanVanVugt

I have created a solution using ActiveSupport::CurrentAttributes instead, fearing thread-safety issues with the approach mentioned above.

# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
  attribute :signed_global_id_expires_at
end
# app/controllers/application_controller.rb
  before_action :set_sgid_expiry

  # Set a default expiry for SGIDs which means that any ids generated within this request will have the same value
  # and can thus be matched on the frontend
  def set_sgid_expiry
    Current.signed_global_id_expires_at = 1.week.from_now
  end
# config/initializers/monkey_patches.rb
# Require all Ruby files in the core_extensions directory
Dir[Rails.root.join('lib', 'patches', '*.rb')].each { |f| require f }

SignedGlobalID.prepend Patches::SignedGlobalID
# lib/patches/signed_global_id.rb
module Patches
  module SignedGlobalID
    def pick_expiration(options)
      return options[:expires_at] if options.key?(:expires_at)
      return options[:expires_in].from_now if options.key?(:expires_in)

      Current.signed_global_id_expires_at || self.class.expires_in&.from_now
    end
  end
end

which succesfully generates the same signed ID on two subsequent calls.

DaanVanVugt avatar Nov 10 '23 10:11 DaanVanVugt