代码之家  ›  专栏  ›  技术社区  ›  bmalets TerryS

Recaptcha gem error“未指定站点密钥”

  •  4
  • bmalets TerryS  · 技术社区  · 8 年前

    我正试图在rails 5应用程序中设置Recaptcha,正如文档中所述,但失败了。

    我用这个宝石: recaptcha (4.6.6) ,则, ruby 2.5.0 rails 5.1.4

    视图形式:

    <%= flash[:recaptcha_error] %>
    <%= recaptcha_tags %>
    

    在设备注册控制器中:

      prepend_before_action :check_captcha, only: :create
    
      private
    
      def check_captcha
        unless verify_recaptcha
          self.resource = resource_class.new sign_up_params
          resource.validate # Look for any other validation errors besides Recaptcha
          respond_with_navigational(resource) { redirect_to new_user_registration_path }
        end 
      end
    

    在我的初始值设定项/recaptcha中。rb型

    Recaptcha.configure do |config|
      config.site_key   = Rails.application.config_for(:recaptcha)['site_key']
      config.secret_key = Rails.application.config_for(:recaptcha)['secret_key']
    end
    

    在我的回顾中。yml:

    default: &default
      site_key: <%= ENV["RECAPTCHA_SITE_KEY"] %>
      secret_key: <%= ENV["RECAPTCHA_SECRET_KEY"] %>
    
    development:
      <<: *default
    
    test:
      <<: *default
    
    staging:
      <<: *default
    
    production:
      <<: *default
    

    在/等/环境中:

    # RECAPTCHA
    RECAPTCHA_SITE_KEY=6Lfg3ksUAAAAABOD_OXCtPO60*******
    RECAPTCHA_SECRET_KEY=6Lfg3ksUAAAAAOmFGdAxdo8*******
    

    问题

    将环境变量添加到 /etc/environments ,我使用以下命令将其导出:

    for line in $( cat /etc/environment ) ; do export $line ; done
    

    然后我检查Recaptcha模块是否正确配置:

    /home/deploy/apps/app_name/current$ bundle exec rails c
    Loading staging environment (Rails 5.1.4) 
    2.5.0 :001 > Recaptcha::Configuration.new
     => #<Recaptcha::Configuration:0x0000000006601908 @skip_verify_env=["test", "cucumber"], @handle_timeouts_gracefully=true, @secret_key="6Lfg3ksUAAAAAOmFGdAxdo8H*************", @site_key="6Lfg3ksUAAAAABOD_OXCtPO*************"> 
    2.5.0 :002 > Recaptcha::Configuration.new.site_key!
     => "6Lfg3ksUAAAAABOD_OXCtPO*************" 
    

    此外,我在运行时看到这些ENV变量 printenv 命令(因此它确实已加载)

    之后,我重新启动了rails,但出现了一个错误

    未指定站点密钥。

    /home/deploy/apps/app_name/shared/bundle/ruby/2.5.0/gems/recaptcha-4.6.6/lib/recaptcha/configuration.rb:47:in `site_key!'
    /home/deploy/apps/app_name/shared/bundle/ruby/2.5.0/gems/recaptcha-4.6.6/lib/recaptcha/client_helper.rb:79:in `recaptcha_components'
    /home/deploy/apps/app_name/shared/bundle/ruby/2.5.0/gems/recaptcha-4.6.6/lib/recaptcha/client_helper.rb:15:in `recaptcha_tags'
    /home/deploy/apps/app_name/releases/20180310222304/app/views/users/registrations/new.html.erb:27:in `block in _app_views_users_registrations_new_html_erb___216558772140569572_69973306795360'
    /home/deploy/apps/app_name/shared/bundle/ruby/2.5.0/gems/actionview-5.1.4/lib/action_view/helpers/capture_helper.rb:39:in `block in capture'
    /home/deploy/apps/app_name/shared/bundle/ruby/2.5.0/gems/actionview-5.1.4/lib/action_view/helpers/capture_helper.rb:203:in `with_output_buffer'
    /home/deploy/apps/app_name/shared/bundle/ruby/2.5.0/gems/actionview-5.1.4/lib/action_view/helpers/capture_helper.rb:39:in `capture'
    /home/deploy/apps/app_name/shared/bundle/ruby/2.5.0/gems/actionview-5.1.4/lib/action_view/helpers/form_helper.rb:450:in `form_for'
    /home/deploy/apps/app_name/releases/20180310222304/app/views/users/registrations/new.html.erb:21:in `_app_views_users_registrations_new_html_erb___216558772140569572_69973306795360'
    /home/deploy/apps/app_name/shared/bundle/ruby/2.5.0/gems/actionview-5.1.4/lib/action_view/template.rb:157:in `block in render'
    
    4 回复  |  直到 8 年前
        1
  •  6
  •   user1846531    7 年前

    我在这里发帖,以防有人正在寻找Rails 5.2解决方案来设置Recaptcha密钥。此解决方案利用新的配置/主控。密钥和配置/凭据。yml。enc加密文件。

    1. 将Recaptcha密钥添加到凭据。yml。通过在本地终端中编辑文件来创建enc文件:

      EDITOR="vim" rails credentials:edit

    2. 将密钥添加到凭据文件后(请参见下面的示例),保存并退出该文件。退出时,凭据。yml。然后,enc文件将自动加密。大师。密钥是应用程序解密所必需的。加密前:

      recaptcha_site_key: 6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy recaptcha_secret_key: 6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxx


    3、创建一个名为config/recaptcha的文件。在Rails应用程序中添加以下代码:
    Recaptcha.configure do |config| config.site_key = Rails.application.credentials.dig(:recaptcha_site_key) config.secret_key = Rails.application.credentials.dig(:recaptcha_secret_key) end

    此解决方案在本地和生产中的Ubuntu/nginx上工作。您不需要gem或环境变量就可以工作。如果主人。密钥解密失败,您可能需要删除这两个凭据。yml。enc文件,甚至可能是主文件。密钥文件,然后在本地重复此过程(EDITOR=“vim”rails凭据:edit等),然后再复制到新的主控形状。生产和重新部署的关键。

        2
  •  0
  •   bmalets TerryS    8 年前

    我仍然不知道“未指定站点密钥”错误的原因是什么。

    我真的不喜欢 gem 'recapthca' 直接使用ENV变量,

    而且我花了太多时间在调查上。

    所以,我决定不使用这个gem,而是编写自己的代码。

    我只使用 Invisible Recaptcha 在我的应用程序中。

    配置文件 (加载密钥和站点密钥)

    # /config/recaptcha.yml
    default: &default
      site_key: <%= ENV["RECAPTCHA_SITE_KEY"] %>
      secret_key: <%= ENV["RECAPTCHA_SECRET_KEY"] %>
    
    development:
      <<: *default
    
    test:
      <<: *default
    
    staging:
      <<: *default
    
    production:
      <<: *default
    

    应用程序帮助程序 (带有Recaptcha帮助器的按钮)

    # /app/helpers/application_helper.rb
    module ApplicationHelper
      def submit_with_recaptcha(text, custom_options)
        unless custom_options[:data].has_key?(:form_id) 
          raise "Data Form Id option not found ('{data: {form_id: 'id_without_dash'}')."
        end
    
        options = {
          type: 'button',
          data: {
            form_id: custom_options[:data][:form_id],
            sitekey: recaptcha_site_key,
            callback: "submit#{custom_options[:data][:form_id].camelize}#{Time.current.to_i}"
          },
          class: (custom_options[:class].split(' ') + ['g-recaptcha']).uniq.join(' ')
        }
    
        script_code = <<-SCRIPT
          function #{options[:data][:callback]}() {
            document.getElementById('#{options[:data][:form_id]}').submit();
          }
        SCRIPT
    
        javascript_tag(script_code) + content_tag(:div, class: 'recaptcha_wrapper'){ submit_tag(text, options) }
      end
    
      private
    
      def recaptcha_site_key
        Rails.application.config_for(:recaptcha)['site_key']
      end
    end
    

    验证服务 (因为它使用外部API)

    # app/services/google_recaptcha/verification.rb
    module GoogleRecaptcha
      # https://developers.google.com/recaptcha/docs/verify
      class Verification
        # response - params['g-recaptcha-response'])
        def self.successful?(recaptcha_params, remoteip)
          verify_url = URI.parse('https://www.google.com/recaptcha/api/siteverify')
          verify_request = Net::HTTP::Post.new(verify_url.path)
    
          verify_request.set_form_data(
            response: recaptcha_params,
            secret: secret_key,
            remoteip: remoteip
          )
    
          connection = Net::HTTP.new(verify_url.host, verify_url.port)
          connection.use_ssl = true
    
          Rails.logger.info '[RECAPTCHA] Sending verification request.'
    
          verify_response = connection.start { |http| http.request(verify_request) }
          response_data = JSON.parse(verify_response.body)
    
          Rails.logger.info "[RECAPTCHA] Verification response is#{' not' unless response_data['success']} successful."
    
          response_data['success']
        end
    
        private
    
        def self.secret_key
          Rails.application.config_for(:recaptcha)['secret_key']
        end
      end
    end
    

    控制器问题 (在before\u action中进行Recaptcha验证)

    # app/controllers/concerns/recaptchable.rb
    module Recaptchable
      extend ActiveSupport::Concern
    
      included do
        before_action :verify_recaptcha, only: [:create]
      end
    
      private
    
      def verify_recaptcha
        unless GoogleRecaptcha::Verification.successful?(recaptcha_params['g-recaptcha-response'], request.remote_ip)
          render :new
          return
        end
      end
    
      def recaptcha_params
        params.permit(:'g-recaptcha-response')
      end
    end
    

    用法

    增加控制器的关注点:

    class MyController < ShopController
      include Recaptchable
    end
    

    添加 www.google.com/recaptcha/api.js 页面的javascript

    添加 submit_with_recaptcha 将助手导入表单

    <%= form_for @delivery, url: users_delivery_path, method: 'post' do |f| %>
      <%= submit_with_recaptcha t('order.deliver.to_confirmation'), data: {form_id: 'new_delivery'}, class: 'btn-round' %>
    
    <% end %>
    <%= javascript_include_tag "https://www.google.com/recaptcha/api.js?hl=#{I18n.locale}", 'data-turbolinks-track': 'reload' %>
    

    就是这样。

        3
  •  0
  •   Pamela Cook - LightBe Corp    7 年前

    注意:我把这个答案贴在这里是为了那些可能会发现这个问题的人。下面是我如何解决这个问题的。

    我使用local\u env。yml表示我的环境变量。我刚开始使用gem,添加了RECAPTCHA\u SITE\u KEY&将cha\u SECRET\u密钥重新发送到local\u env。yml。我也犯了同样的错误。

    花了一点时间才发现gem直接使用了这些变量。我最后在 ~/.bashrc 与文档所述内容类似,但在值周围没有引号。

    export RECAPTCHA_SITE_KEY=6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy
    export RECAPTCHA_SECRET_KEY=6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx
    

    我在Heroku上托管我的应用程序。我执行了以下终端命令来设置Heroku中的环境变量。

    heroku config:set RECAPTCHA_SITE_KEY=‘6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy’
    heroku config:set RECAPTCHA_SECRET_KEY=‘6LcGuI4U6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxxAAAAGAWMYRKFGfHUCSD0SPrMX2lfyl9’
    
        4
  •  0
  •   mvanio    7 年前

    您正在使用nginx吗?Nginx删除了环境变量(TZ除外),似乎recaptcha gem对此特别敏感。根据经验,当使用 dotenv gem其他环境变量工作正常,recaptcha环境变量被忽略。

    您可以通过在nginx的顶部添加env变量来解决这个问题。形态。

    env RECAPTCHA_SITE_KEY=value1;
    env RECAPTCHA_SECRET_KEY=value2;
    

    Here's nginx's documentation on the matter.