123456789_123456789_123456789_123456789_123456789_

Class: ActionDispatch::Cookies::EncryptedKeyRotatingCookieJar

Do not use. This class is for internal use only.
Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: ActionDispatch::Cookies::AbstractCookieJar
Defined in: actionpack/lib/action_dispatch/middleware/cookies.rb

Constant Summary

SerializedCookieJars - Included

SERIALIZER

Class Method Summary

AbstractCookieJar - Inherited

Instance Attribute Summary

Instance Method Summary

SerializedCookieJars - Included

AbstractCookieJar - Inherited

ChainedCookieJars - Included

#encrypted

Returns a jar that'll automatically encrypt cookie values before sending them to the client and will decrypt them for read.

#permanent

Returns a jar that'll automatically set the assigned cookies to have an expiration date 20 years from now.

#signed

Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from the cookie again.

#signed_or_encrypted

Returns the signed or encrypted jar, preferring encrypted if secret_key_base is set.

#encrypted_cookie_cipher, #signed_cookie_digest

Constructor Details

This class inherits a constructor from ActionDispatch::Cookies::AbstractCookieJar

Instance Method Details

#commit(name, options) (private)

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 707

def commit(name, options)
  super
  options[:value] = encryptor.encrypt_and_sign(options[:value], **(name, options))
  check_for_overflow!(name, options)
end

#encryptor (private)

Built on first use: reading a cookie the request doesn't have never needs it.

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 664

def encryptor
  @encryptor ||= begin
    if request.use_authenticated_cookie_encryption
      key_len = ActiveSupport::MessageEncryptor.key_len(encrypted_cookie_cipher)
      secret = request.key_generator.generate_key(request.authenticated_encrypted_cookie_salt, key_len)
      encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: encrypted_cookie_cipher, serializer: SERIALIZER)
    else
      key_len = ActiveSupport::MessageEncryptor.key_len("aes-256-cbc")
      secret = request.key_generator.generate_key(request.encrypted_cookie_salt, key_len)
      sign_secret = request.key_generator.generate_key(request.encrypted_signed_cookie_salt)
      encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, cipher: "aes-256-cbc", serializer: SERIALIZER)
    end

    request.cookies_rotations.encrypted.each do |(*secrets)|
      options = secrets.extract_options!
      encryptor.rotate(*secrets, serializer: SERIALIZER, **options)
    end

    if upgrade_legacy_hmac_aes_cbc_cookies?
      legacy_cipher = "aes-256-cbc"
      secret = request.key_generator.generate_key(request.encrypted_cookie_salt, ActiveSupport::MessageEncryptor.key_len(legacy_cipher))
      sign_secret = request.key_generator.generate_key(request.encrypted_signed_cookie_salt)

      encryptor.rotate(secret, sign_secret, cipher: legacy_cipher, digest: digest, serializer: SERIALIZER)
    elsif prepare_upgrade_legacy_hmac_aes_cbc_cookies?
      future_cipher = encrypted_cookie_cipher
      secret = request.key_generator.generate_key(request.authenticated_encrypted_cookie_salt, ActiveSupport::MessageEncryptor.key_len(future_cipher))

      encryptor.rotate(secret, nil, cipher: future_cipher, serializer: SERIALIZER)
    end

    encryptor
  end
end

#parse(name, encrypted_message, purpose: nil) (private)

[ GitHub ]

  
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 699

def parse(name, encrypted_message, purpose: nil)
  rotated = false
  data = encryptor.decrypt_and_verify(encrypted_message, purpose: purpose, on_rotation: -> { rotated = true })
  super(name, data, force_reserialize: rotated)
rescue ActiveSupport::MessageEncryptor::InvalidMessage, ActiveSupport::MessageVerifier::InvalidSignature
  nil
end