Rails 无法在 class 初始化方法中生成实例变量以生成 httparty 请求

Rails unable to generate instance variable in class initialize method to generate httparty request

我在通过 Ruby class 生成 Signature 时遇到问题。当我进入我的 docker 容器时,我能够看到 initialize 方法中的所有实例变量都是 nil 期望 @api_key 变量。

我有以下class

require 'openssl'
require 'base64'

module SeamlessGov
  class Form
    include HTTParty
    attr_accessor :form_id
    base_uri "https://nycopp.seamlessdocs.com/api"

    def initialize()
      @api_key = ENV['SEAMLESS_GOV_API_KEY']
      @signature = generate_signature
      @form_id = ENV['SEAMLESS_GOV_FORM_ID']
      @timestamp = Time.now.to_i.to_s
    end

    def relative_uri
      "/form/#{@form_id}/elements"
    end

    def create_form
      self.class.get(relative_uri, headers: generate_headers)
    end

    private

    def generate_signature
      OpenSSL::HMAC.hexdigest('sha256', ENV['SEAMLESS_GOV_SECRET'], "GET+#{relative_uri}+#{@timestamp}")
      binding.pry
    end

    def generate_headers
      {
        "Authorization"  => "HMAC-SHA256 api_key='#{@api_key}' signature='#{@timestamp}'",
         Net::HTTP::ImmutableHeaderKey.new('AuthDate') => "#{@timestamp}"
      }
    end
  end
end

如您所见,从 generate_signature 方法中的 binding.pry 我可以看到实例变量:

生成签名所需的 relative_uri 方法未加载字符串中的 @form_id 变量。

这是控制器:

class FormsController < ApplicationController
  def display_form
    @form = SeamlessGov::Form.new().create_form
  end
end

解决 net/http headers 区分大小写问题: lib/net_http

require 'net/http'

class Net::HTTP::ImmutableHeaderKey
  attr_reader :key

  def initialize(key)
    @key = key
  end

  def downcase
    self
  end

  def capitalize
    self
  end

  def split(*)
    [self]
  end

  def hash
    key.hash
  end

  def eql?(other)
    key.eql? other.key.eql?
  end

  def to_s
    def self.to_s
      key
    end
    self
  end
end

如果我调用 create_form 这是输出:

{"error"=>true,
 "error_log"=>
  [{"error_code"=>"missing_date_headers",
    "error_message"=>"Request is missing date headers",
    "error_description"=>
     "{\"Host\":\"nycopp.seamlessdocs.com\",\"Connection\":\"close\",\"X-Real-IP\":\"71.249.243.7\",\"X-Forwarded-For\":\"71.249.243.7\",\"X-Forwarded-Host\":\"nycopp.seamlessdocs.com\",\"X-Forwarded-Port\":\"443\",\"X-Forwarded-Proto\":\"https\",\"X-Original-URI\":\"\/api\/form\/\/elements\",\"X-Scheme\":\"https\",\"Authorization\":\"HMAC-SHA256 api_key='h123xxxxxxxxxx' signature=''\",\"AuthDate\":\"\"}"},
   {"error_code"=>"external_auth_error", "error_message"=>"Date header is missing or timestamp out of bounds"}]}

有什么问题?

错误的顺序是operations/calculations。

def initialize()
  @api_key = ENV['SEAMLESS_GOV_API_KEY']
  @signature = generate_signature # <= at this point, neither form_id nor timestamp are set. but api key is.
  @form_id = ENV['SEAMLESS_GOV_FORM_ID']
  @timestamp = Time.now.to_i.to_s
end