【问题标题】:Google Service Account authorize() returns invalid_grant errorGoogle 服务帐户授权()返回 invalid_grant 错误
【发布时间】:2014-07-19 20:39:50
【问题描述】:

我已经仔细查看了 Steve Bazyl 在 https://www.youtube.com/watch?v=iK14bfd6qhs 的演示文稿以及 google 上的相关 API 文档。我正在为我的 gmail 帐户使用服务帐户电子邮件 ID,并且正在使用从控制台下载的私钥。

但是当我按照史蒂夫在他的演示文稿中展示的那个模型运行测试客户端时,我一直得到

 Signet::AuthorizationError:
   Authorization failed.  Server message:
   {
     "error" : "invalid_grant"
   }

如果我将垃圾信添加到传递给 JWTAsserter 的电子邮件或范围,我会收到相同的错误消息。显然出了点问题,但我似乎不知道如何解决这个问题。

这是我正在运行的客户端代码(在 rails rspec 文件中):

client = Google::APIClient.new

key_file = '/Users/stu/projects/br/rails-app/######-privatekey.p12'
key = Google::APIClient::KeyUtils.load_from_pkcs12(key_file, 'notasecret')
Rails.logger.info "Private key? #{key.private?}"

asserter = Google::APIClient::JWTAsserter.new( 
  '#####-#######knp@developer.gserviceaccount.com', 
  "https://www.googleapis.com/auth/calendar", 
  key)
client.authorization = asserter.authorize()

我被卡住了,如果有任何故障排除建议,我将不胜感激。

谢谢!

更新

感谢您分享适合您的代码,Jack。

我已访问我网站的开发控制台并创建了一个服务帐户客户端 p12 密钥。然后,我转到站点的管理控制台并添加了我的客户端 ID,以向日历 API 授予站点范围的授权

在添加授权后的管理控制台中,它看起来像这样: XXXXXXXXXXXXhnq.apps.googleusercontent.com 日历(读写)https://www.googleapis.com/auth/calendar

我下载了 p12 密钥,并在您提供的代码结构中使用了它。我还尝试了 Steve Bazyl 演讲中的方法:

asserter = Google::APIClient::JWTAsserter.new( 
  "XXXXXXXXXXX-hnq@developer.gserviceaccount.com", 
  "https://www.googleapis.com/auth/calendar", 
  key)
client.authorization = asserter.authorize("stu@XXXXXXXXXX.com")

在这两种情况下,我都会得到与以前相同的输出:

 Signet::AuthorizationError:
   Authorization failed.  Server message:
   {
     "error" : "invalid_grant"
   }

如果我输入 junk 而不是“XXXXs://www.googleapis.com/auth/calendar”,我会得到相同的输出。密钥是有效的,虽然很明显我做错了什么,但我在 API 或谷歌中找不到任何关于如何判断它的线索。

有任何解决问题的想法吗?

【问题讨论】:

    标签: google-api-ruby-client


    【解决方案1】:

    您是否已授予服务帐户访问您的 Google Apps 帐户的权限?您可以在此处了解如何操作:https://developers.google.com/+/domains/authentication/delegation#delegate_domain-wide_authority_to_your_service_account

    以下代码对我有用:

    key = Google::APIClient::KeyUtils.load_from_pkcs12('tmp/##########-privatekey.p12', 'notasecret')
    client = Google::APIClient.new({:application_name => "example-app", :application_version => "1.0"})
    client.authorization = Signet::OAuth2::Client.new(
      :person => 'name@example.com',
      :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
      :audience => 'https://accounts.google.com/o/oauth2/token',
      :scope => 'https://www.googleapis.com/auth/drive.readonly',
      :issuer => '123456789@developer.gserviceaccount.com',
      :signing_key => key)
    client.authorization.fetch_access_token!
    
    drive = client.discovered_api('drive', 'v2')
    result = client.execute(api_method: drive.files.list)
    

    【讨论】:

    • 感谢您分享适合您的代码。试过了,还是卡住了
    【解决方案2】:

    a long thread regarding this on GitHub 似乎表明问题与系统的日期和时间“有点偏差”有关。建议的解决方案是运行sudo ntpdate ntp.ubuntu.com

    线程已关闭,但它确实有指向this information from Google about "Invalid Grant" 的链接。

    【讨论】:

      【解决方案3】:

      永远无法弄清楚如何克服 invalid_grant 错误。

      我的解决方案是使用普通的 webapp api 获取刷新令牌。一旦检索到,它似乎可以无限期使用,因此最终结果似乎是相同的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-22
        • 2017-06-13
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多