Skip to content
  • Ali Sepehri's avatar
    e4218ff3
    Use Rails.application.message_verifiers for signed IDs · e4218ff3
    Ali Sepehri authored
    
    
    Prior to this change, the primary way to configure signed ID verifiers
    was to set `signed_id_verifier` on each model class:
    
      ```ruby
      Post.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
      Comment.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
      ```
    
    And if the developer did not set `signed_id_verifier`, a verifier would
    be instantiated with a secret derived from `secret_key_base` and the
    following options:
    
      ```ruby
      { digest: "SHA256", serializer: JSON, url_safe: true }
      ```
    
    Thus it was cumbersome to rotate configuration for all verifiers.
    
    This change defines a new Rails config: `config.active_record.use_legacy_signed_id_verifier`.
    The default value is `:generate_and_verify`, which preserves the
    previous behavior.  However, when set to `:verify`, signed ID verifiers
    will use configuration from `Rails.application.message_verifiers` to
    generate and verify signed IDs, but will also verify signed IDs using
    the older configuration.
    
    To avoid complication, the new behavior only applies when `signed_id_verifier_secret`
    is not set on a model class, and `signed_id_verifier_secret` is now
    deprecated.  Instead of setting `signed_id_verifier_secret`, developers
    can set `signed_id_verifier`:
    
      ```ruby
      # BEFORE
      Post.signed_id_verifier_secret = "my secret"
    
      # AFTER
      Post.signed_id_verifier = ActiveSupport::MessageVerifier.new("my secret", digest: "SHA256", serializer: JSON, url_safe: true)
      ```
    
    To ease migration, `signed_id_verifier` has also been changed to behave as a
    `class_attribute` (i.e. inheritable), but _only when `signed_id_verifier_secret`
    is not set_:
    
      ```ruby
      # BEFORE
      ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
      Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
    
      # AFTER
      ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
      Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => true
    
      Post.signed_id_verifier_secret = "my secret" # => deprecation warning
      Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
      ```
    
    Co-authored-by: default avatarJonathan Hefner <jonathan@hefner.pro>
    e4218ff3
    Use Rails.application.message_verifiers for signed IDs
    Ali Sepehri authored
    
    
    Prior to this change, the primary way to configure signed ID verifiers
    was to set `signed_id_verifier` on each model class:
    
      ```ruby
      Post.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
      Comment.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
      ```
    
    And if the developer did not set `signed_id_verifier`, a verifier would
    be instantiated with a secret derived from `secret_key_base` and the
    following options:
    
      ```ruby
      { digest: "SHA256", serializer: JSON, url_safe: true }
      ```
    
    Thus it was cumbersome to rotate configuration for all verifiers.
    
    This change defines a new Rails config: `config.active_record.use_legacy_signed_id_verifier`.
    The default value is `:generate_and_verify`, which preserves the
    previous behavior.  However, when set to `:verify`, signed ID verifiers
    will use configuration from `Rails.application.message_verifiers` to
    generate and verify signed IDs, but will also verify signed IDs using
    the older configuration.
    
    To avoid complication, the new behavior only applies when `signed_id_verifier_secret`
    is not set on a model class, and `signed_id_verifier_secret` is now
    deprecated.  Instead of setting `signed_id_verifier_secret`, developers
    can set `signed_id_verifier`:
    
      ```ruby
      # BEFORE
      Post.signed_id_verifier_secret = "my secret"
    
      # AFTER
      Post.signed_id_verifier = ActiveSupport::MessageVerifier.new("my secret", digest: "SHA256", serializer: JSON, url_safe: true)
      ```
    
    To ease migration, `signed_id_verifier` has also been changed to behave as a
    `class_attribute` (i.e. inheritable), but _only when `signed_id_verifier_secret`
    is not set_:
    
      ```ruby
      # BEFORE
      ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
      Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
    
      # AFTER
      ActiveRecord::Base.signed_id_verifier = ActiveSupport::MessageVerifier.new(...)
      Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => true
    
      Post.signed_id_verifier_secret = "my secret" # => deprecation warning
      Post.signed_id_verifier == ActiveRecord::Base.signed_id_verifier # => false
      ```
    
    Co-authored-by: default avatarJonathan Hefner <jonathan@hefner.pro>
Loading