简体   繁体   English

无法通过Google Content API for Shopping进行身份验证

[英]Trouble authenticating with Google Content API for Shopping

I'm trying to use OAuth2 for Server to Server Applications in conjunction with Google's Content API for Shopping using the google-api-client gem and Ruby on Rails 3.2.5. 我正在尝试将OAuth2用于服务器到服务器应用程序 ,并结合Google的Content API for Shopping使用google-api-client gem和Ruby on Rails 3.2.5。 Also, I have already set up my merchant account as prescribed in the Content API documentation. 此外,我已按照Content API文档中的规定设置了我的商家帐户。

This was the best way I found to be able to: 这是我发现能够:

  • create/update products in the background 在后台创建/更新产品
  • have created products fall under my company's Google Products 'umbrella' 已创建产品属于我公司的Google产品“保护伞”
  • not require every user to authenticate/authorize when their token expires 当令牌过期时,不要求每个用户进行身份验证/授权

Using lines 1 - 23 from this sample as a starting point, I've begun to write the following module for use in background jobs: 使用此示例中的第1 - 23行作为起点,我已经开始编写以下模块以用于后台作业:

require 'httparty'
require 'google/api_client'

module GoogleProducts
  GOOGLE_CONFIG = YAML.load_file(File.join(Rails.root, "config", "google.yml"))[Rails.env]

  CLIENT_ID = "XXXXXXXXXXXX@developer.gserviceaccount.com"
  MERCHANT_ID = "XXXXXXX"
  SCOPE = "https://www.googleapis.com/auth/structuredcontent"

  KEY_FILE_PATH = File.join(Rails.root, "config", "my-privatekey.p12")
  KEY_FILE_PASS = "XXXXXXXXXX"

  def self.add_item(item_id)
    self.fetch_token
    xml = self.gen_item_xml(item_id)
    headers = {"Content-type" => "application/atom+xml", "Content-Length" => xml.length.to_s}
    url = "https://content.googleapis.com/content/v1/#{MERCHANT_ID}/items/products/generic?access_token=#{$gp_token}"

    response = HTTParty.post(url, :body => xml, :headers => headers).parsed_response
  end

  def self.gen_item_xml(item_id)
    #building product xml
  end

  private
  def self.fetch_token
    api_client = Google::APIClient.new(:authorization => :oauth2)
    key = Google::APIClient::PKCS12.load_key(KEY_FILE_PATH, KEY_FILE_PASS)
    asserter = Google::APIClient::JWTAsserter.new(CLIENT_ID, SCOPE, key)

    begin
      api_client.authorization = asserter.authorize

      #todo - store in something other than a global
      $gp_token = api_client.authorization.access_token
    rescue Signet::AuthorizationError => e
      puts e.message
    ensure
      return $gp_token
    end
  end
end

Everything seemingly works fine - the authentication, the handling of the auth token - until I attempt to actually add an item, which I get the following when I do: 一切似乎都运行良好 - 身份验证,身份验证令牌的处理 - 直到我尝试实际添加一个项目,当我这样做时,我得到以下内容:

<errors xmlns='http://schemas.google.com/g/2005'>
  <error>
    <domain>GData</domain>
    <code>ServiceForbiddenException</code>
    <internalReason>Could not find authenticated customer</internalReason>
  </error>
</errors>

Any ideas? 有任何想法吗?

After much anguish and mental toil, I've finally solved my issue! 经过多次痛苦和精神上的辛劳,我终于解决了我的问题!

Since I am using OAuth 2 Server to Server authentication the suggestion hjblok gave didn't apply (thanks for giving it a shot, though!). 由于我使用的是OAuth 2服务器到服务器身份验证,因此hjblok给出的建议不适用(感谢给它一个镜头,但是!)。

I simply added the email address that was associated with my Service Account key from the Google API Console (eg XXXXXXXXXXXX@developer.gserviceaccount.com ) to my Google Merchant account ( Settings > Users on the merchant admin page), and it worked. 我只是将与我的服务帐户密钥相关联的电子邮件地址从Google API控制台(例如XXXXXXXXXXXX@developer.gserviceaccount.com )添加到我的Google Merchant帐户(商家管理页面上的Settings > Users ),并且它有效。

If there's any clarification needed, please feel free to comment! 如果需要任何澄清,请随时发表评论!

The Google Content API documentation says you need to set it up in the Settings page of the Google Merchant Center: Google Content API文档说明您需要在Google Merchant Center的“设置”页面中进行设置:

https://developers.google.com/shopping-content/getting-started/usingapi-products https://developers.google.com/shopping-content/getting-started/usingapi-products

EDIT rewrote the answer after diving into the Google's API documentation 在深入了解Google的API文档后, EDIT重写了答案

Did you already try to use Google's OAuth 2.0 playground ? 您是否已尝试使用Google的OAuth 2.0游乐场 I was able to successfully access https://content.googleapis.com/content/v1/#{MERCHANT_ID}/items/products/generic . 我能够成功访问https://content.googleapis.com/content/v1/#{MERCHANT_ID}/items/products/generic

  1. In "Step 1" I've chosen the "Content API for Shopping" and then authorized the API with my account. 在“第1步”中,我选择了“Content API for Shopping”,然后使用我的帐户授权API。
  2. Then in "Step 2" I've "exchanged authorization code for tokens", which results in a "refresh token" and an "access token". 然后在“步骤2”中,我“交换了令牌的授权码”,这导致了“刷新令牌”和“访问令牌”。
  3. Then in "Step 3" I've invoked a GET request to https://content.googleapis.com/content/v1/1234567/items/products/generic . 然后在“步骤3”中,我调用了一个GET请求到https://content.googleapis.com/content/v1/1234567/items/products/generic Because 1234567 is not a valid MERCHANT_ID it returns an Error. 由于1234567不是有效的MERCHANT_ID因此返回错误。 But the Error Messages contains a MERCHANT_ID which actually belongs to your account. 但错误消息包含实际属于您的帐户的MERCHANT_ID
  4. I repeated "Step 3" but now with the correct MERCHANT_ID . 我重复了“第3步”但现在使用了正确的MERCHANT_ID Which returns a HTTP/1.1 200 OK with the requested items in the body. 返回HTTP/1.1 200 OK ,包含正文中的请求项。

Furthermore I'm not sure, but doesn't Google API expect an Authorization header to be present with the access_token ( $gp_token )? 此外,我不确定,但Google API是否期望授权标头与access_token$gp_token )一起出现? Within the OAuth 2.0 playground this Authorization header is used to sent the access_token . OAuth 2.0操场中,此Authorization标头用于发送access_token

I also found the Structured Content API demo page (https://google-content-api-tools.appspot.com/demo/demo.html), which is more specific to the Content API for Shopping. 我还找到了结构化内容API演示页面(https://google-content-api-tools.appspot.com/demo/demo.html),该页面更适用于Content API for Shopping。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM