Rails 7部署至Heroku构建失败:LinkedIn认证凭证报错
问题
我正在开发一个基于Ruby on Rails 7的Web应用,用omniauth-linkedin-oauth2 gem实现LinkedIn登录认证。本地通过config/credentials.yml.enc配置凭证后运行正常,但部署到Heroku时,资产预编译阶段抛出以下错误:
NoMethodError: undefined method `[]' for nil:NilClass config.omniauth :linkedin, Rails.application.credentials[:linkedin][:client_id], Rails.application.credentials[:linkedin][:client_secret]
我已经确认config/credentials.yml.enc和Heroku应用的配置变量里的LinkedIn凭证都配置正确,但还是触发报错,需要解决这个部署问题,成功把Rails 7应用推到Heroku。
部署时的完整错误日志:
Fetching sassc-rails 2.1.2 Installing sassc-rails 2.1.2 Installing font-awesome-sass 6.4.0 Bundle complete! 24 Gemfile dependencies, 81 gems now installed. Gems in the groups 'development' and 'test' were not installed. Bundled gems are installed into `./vendor/bundle` Post-install message from devise: [DEVISE] Please review the [changelog] and [upgrade guide] for more info on Hotwire / Turbo integration. [changelog] https://github.com/heartcombo/devise/blob/main/CHANGELOG.md [upgrade guide] https://github.com/heartcombo/devise/wiki/How-To:-Upgrade-to-Devise-4.9.0-%5BHotwire-Turbo-integration%5D Post-install message from oauth2: You have installed oauth2 version 2.0.9, congratulations! There are BREAKING changes if you are upgrading from < v2, but most will not encounter them, and updating your code should be easy! We have made two other major migrations: 1. master branch renamed to main 2. Github has been replaced with Gitlab Please see: • https://gitlab.com/oauth-xx/oauth2#what-is-new-for-v20 • https://gitlab.com/oauth-xx/oauth2/-/blob/main/CHANGELOG.md • https://groups.google.com/g/oauth-ruby/c/QA_dtrXWXaE Please report issues, and support the project! Thanks, |7eter l-|. l3oling Bundle completed (86.58s) Cleaning up the bundler cache. -----> Installing node-v16.18.1-linux-x64 -----> Installing yarn-v1.22.19 -----> Detecting rake tasks -----> Preparing app for Rails asset pipeline Running: rake assets:precompile rake aborted! NoMethodError: undefined method `[]' for nil:NilClass config.omniauth :linkedin, Rails.application.credentials[:linkedin][:client_id], Rails.application.credentials[:linkedin][:client_secret] ^^^^^^^^^^^^ /tmp/build_22da9b42/config/initializers/devise.rb:14:in `block in <main>' /tmp/build_22da9b42/vendor/bundle/ruby/3.1.0/gems/devise-4.9.2/lib/devise.rb:314:in `setup' /tmp/build_22da9b42/config/initializers/devise.rb:11:in `<main>' /tmp/build_22da9b42/vendor/bundle/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:667:in `load' /tmp/build_22da9b42/vendor/bundle/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:667:in `block in load_config_initializer' /tmp/build_22da9b42/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.3/lib/active_support/notifications.rb:208:in `instrument' /tmp/build_22da9b42/vendor/bundle/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:666:in `load_config_initializer' /tmp/build_22da9b42/vendor/bundle/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:620:in `block (2 levels) in <class:Engine>'
解决方案
- 配置Heroku的RAILS_MASTER_KEY:Rails 7的
credentials.yml.enc需要用master.key解密,把本地config/master.key文件的内容添加到Heroku的环境变量中(变量名设为RAILS_MASTER_KEY)。如果缺少这个变量,部署时无法读取credentials里的内容,就会出现nil调用[]的错误。 - 改用环境变量直接读取:放弃credentials方式,直接从环境变量获取凭证。修改
config/initializers/devise.rb里的代码:
然后在Heroku的应用设置里添加config.omniauth :linkedin, ENV['LINKEDIN_CLIENT_ID'], ENV['LINKEDIN_CLIENT_SECRET']LINKEDIN_CLIENT_ID和LINKEDIN_CLIENT_SECRET两个环境变量,本地开发可以用dotenv-railsgem,在.env文件里配置这两个变量。 - 避免预编译时加载认证配置:资产预编译不需要加载omniauth的配置,在
devise.rb里加条件判断,只在非预编译阶段加载:unless defined?(Rails.application.config.assets_precompile) && Rails.application.config.assets_precompile config.omniauth :linkedin, Rails.application.credentials[:linkedin][:client_id], Rails.application.credentials[:linkedin][:client_secret] end - 检查Heroku的Rails环境变量:确认Heroku的
RAILS_ENV设置为production,并且所有凭证变量都配置在production环境下,不要误放到development或test环境。
内容的提问来源于stack exchange,提问作者Wilson CELY
相关产品推荐
相关产品推荐

