Google服务帐户authorize()会返回invalid_grant错误

时间:2014-05-30 06:44:42

标签: google-api-ruby-client

我仔细阅读了Steve Bazyl在https://www.youtube.com/watch?v=iK14bfd6qhs上的演示文稿以及谷歌上的相关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()

我很卡住,绝对会感谢任何故障排除建议。

谢谢!

更新

感谢您分享适合您的代码杰克。

我已经访问了我网站的开发控制台,并创建了一个服务帐户客户端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中的任何线索或谷歌如何判断它是什么。

任何想法如何排查?

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

从来没有弄清楚如何通过invalid_grant错误。

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