从Rails引擎初始化程序访问主要应用程序机密

Aug*_*tos 8 ruby-on-rails rails-engines

我一直在尝试(不成功)从我的Rails可安装引擎中访问主应用程序的应用程序机密.可安装引擎的重点是提供模块化.因此,常见的模式是在主应用程序中提供可配置的参数,其中一些参数需要是秘密的,然后引擎将使用这些参数.

在我的具体情况下,我在我的引擎中使用carrierwave和fog将文件上传到AWS桶.确切的存储桶和AWS凭证未在引擎中指定,但在主应用程序中指定,因为它们会因安装引擎的应用程序而异.

但是,当安装在引擎中时,carrierwave的初始化程序失败,因为它无法找到主应用程序的Rails.application.secrets:

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
Run Code Online (Sandbox Code Playgroud)

启动引擎时失败

Missing required arguments: aws_access_key_id, aws_secret_access_key (ArgumentError)
Run Code Online (Sandbox Code Playgroud)

事实上Rails.application.secrets.S3_AWS_ACCESS_KEY_ID(和其他人)nil在初始化程序中进行评估.一旦应用程序运行,它确实在引擎控制器内正确评估,但在初始化程序中它是零.

我修改了这个如下:

:aws_access_key_id      => Rails.application.secrets.S3_AWS_ACCESS_KEY_ID || ENV["S3_AWS_ACCESS_KEY_ID"]
Run Code Online (Sandbox Code Playgroud)

并在每个生产环境中输出ENV VARIABLE以供引擎使用,但这并不理想.任何解决方案将不胜感激.

小智 1

  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

Run Code Online (Sandbox Code Playgroud)
  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

Run Code Online (Sandbox Code Playgroud)
  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

Run Code Online (Sandbox Code Playgroud)

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