访问Rails Engine Initializer的主要应用程序秘密



我一直在尝试(失败)从我的轨道上可安装的引擎中访问主应用程序的秘密。可安装发动机的全部点是提供模块化。因此,一个常见的模式是提供可配置的参数,其中一些需要在主应用中秘密,然后由引擎使用。

在我的特定情况下,我正在使用引擎中的carrierwavefog将文件上传到AWS存储桶。确切的存储桶和AWS凭据在引擎中未指定,而是在主要应用中指定的,因为它们将改变发动机的应用程序。

但是,安装在发动机中时的载波初始化器失败,因为它找不到轨道。

require 'carrierwave'
require 'carrierwave/storage/fog'
CarrierWave.configure do |config|
  config.fog_provider = 'fog/aws'
  config.fog_credentials = {
    :provider               => 'AWS',
  :aws_access_key_id      => Rails.application.secrets.S3_AWS_ACCESS_KEY_ID,
  :aws_secret_access_key  => Rails.application.secrets.S3_AWS_SECRET_ACCESS_KEY
  }
  config.fog_directory  = Rails.application.secrets.CARRIERWAVE_CONFIG_FOG_DIRECTORY
  config.storage = :fog
end

启动引擎时,这将失败
Missing required arguments: aws_access_key_id, aws_secret_access_key (ArgumentError)

实际上Rails.application.secrets.S3_AWS_ACCESS_KEY_ID(以及其他)在初始化器中评估nil。该应用程序运行后,它确实在发动机控制器内部进行了正确的评估,但是在初始化器中为nil。

我已经像以下几个:

进行了修改:
:aws_access_key_id      => Rails.application.secrets.S3_AWS_ACCESS_KEY_ID || ENV["S3_AWS_ACCESS_KEY_ID"]

并在每个生产环境中导出ENV变量以与发动机一起使用,但这并不理想。任何解决方案都将不胜感激。

  1. 在引擎的初始化器(config/initializers/Engine_name.rb)中,定义了存储AWS凭据和雾目录的配置选项:
# config/initializers/engine_name.rb
EngineName.configure do |config|
  config.aws_access_key_id = nil
  config.aws_secret_access_key = nil
  config.fog_directory = nil
end
  1. 在主应用程序中,在初始化器中提供这些配置选项的值:
# config/initializers/engine_name.rb
EngineName.configure do |config|
  config.aws_access_key_id = Rails.application.secrets.S3_AWS_ACCESS_KEY_ID
  config.aws_secret_access_key = Rails.application.secrets.S3_AWS_SECRET_ACCESS_KEY
  config.fog_directory = Rails.application.secrets.CARRIERWAVE_CONFIG_FOG_DIRECTORY
end
  1. 修改引擎中的载波初始化器以使用配置选项:
# engine_name/config/initializers/carrierwave.rb
require 'carrierwave'
require 'carrierwave/storage/fog'
CarrierWave.configure do |config|
  config.fog_provider = 'fog/aws'
  config.fog_credentials = {
    provider: 'AWS',
    aws_access_key_id: EngineName.configuration.aws_access_key_id,
    aws_secret_access_key: EngineName.configuration.aws_secret_access_key
  }
  config.fog_directory = EngineName.configuration.fog_directory
  config.storage = :fog
end

通过使用这种方法,您允许主应用程序通过引擎的配置提供必要的秘密,从而避免了直接从引擎访问主应用程序的问题。

您应该能够访问引擎初始化器的秘密。


# path/to/your/engine/my_engine/lib/my_engine/engine.rb
module MyEngine
    class Engine
        initializer :my_custom_initializer do |app|
            puts app.secrets
        end
    end
end

最新更新