3

我已经仔细查看了 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 授予站点范围的授权

在添加授权后的管理控制台中,它看起来像这样: XXXXXXXXXXXhnq.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"
   }

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

任何想法如何解决?

4

3 回答 3

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)
于 2014-05-30T10:43:31.070 回答
1

在 GitHub 上有一个关于此的长线程,这似乎表明该问题与系统的日期和时间“有点偏差”有关。建议的解决方案是运行sudo ntpdate ntp.ubuntu.com.

该线程已关闭,但它确实具有来自 Google 的有关“无效授权”的此信息的链接。

于 2016-12-20T22:40:30.820 回答
0

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

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

于 2014-06-02T05:56:07.113 回答