Google表格API v4 service_account – 禁止:来电者没有权限(Google :: Apis :: ClientError)

Ruby:2.3.1

Rails:5.0.0

我需要通过Google表格API访问和更新我的私人Google表格。 最终,这应该由我的Rails应用程序中的重复后台作业完成。 因此,我在Google云端控制台中设置了服务帐户。

但是要开始使用Google表格API,我创建了一个脚本:

require 'google/apis/sheets_v4' ENV["GOOGLE_ACCOUNT_TYPE"] = 'service_account' ENV["GOOGLE_CLIENT_EMAIL"] = '' ENV["GOOGLE_PRIVATE_KEY"] = "" SCOPE = Google::Apis::SheetsV4::AUTH_SPREADSHEETS authorization = Google::Auth.get_application_default(SCOPE) # Initialize the API service = Google::Apis::SheetsV4::SheetsService.new service.authorization = authorization spreadsheet_id = '' sheet_name = 'Sheet1' range = "#{sheet_name}!A2:B" response = service.get_spreadsheet_values(spreadsheet_id, range) puts 'No data found.' if response.values.empty? response.values.each do |row| # Print columns A and B, which correspond to indices 0 and 1. puts "#{row[0]}, #{row[1]}" end 

当我运行该脚本时

 $ rails runner -e development lib/scripts/google_sheets_api_demo.rb /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/google-api-client-0.9.12/lib/google/apis/core/http_command.rb:211:in `check_status': forbidden: The caller does not have permission (Google::Apis::ClientError) from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/google-api-client-0.9.12/lib/google/apis/core/api_command.rb:102:in `check_status' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/google-api-client-0.9.12/lib/google/apis/core/http_command.rb:179:in `process_response' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/google-api-client-0.9.12/lib/google/apis/core/http_command.rb:286:in `execute_once' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/google-api-client-0.9.12/lib/google/apis/core/http_command.rb:107:in `block (2 levels) in execute' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/retriable-2.1.0/lib/retriable.rb:54:in `block in retriable' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/retriable-2.1.0/lib/retriable.rb:48:in `times' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/retriable-2.1.0/lib/retriable.rb:48:in `retriable' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/google-api-client-0.9.12/lib/google/apis/core/http_command.rb:104:in `block in execute' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/retriable-2.1.0/lib/retriable.rb:54:in `block in retriable' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/retriable-2.1.0/lib/retriable.rb:48:in `times' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/retriable-2.1.0/lib/retriable.rb:48:in `retriable' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/google-api-client-0.9.12/lib/google/apis/core/http_command.rb:96:in `execute' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/google-api-client-0.9.12/lib/google/apis/core/base_service.rb:346:in `execute_or_queue_command' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/google-api-client-0.9.12/generated/google/apis/sheets_v4/service.rb:322:in `get_spreadsheet_values' from lib/scripts/google_sheets_api_demo.rb:35:in `' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/railties-5.0.0/lib/rails/commands/runner.rb:60:in `load' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/railties-5.0.0/lib/rails/commands/runner.rb:60:in `' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:138:in `require' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:138:in `require_command!' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:104:in `runner' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:49:in `run_command!' from /home/jignesh/.rvm/gems/ruby-2.3.1@my_integrations/gems/railties-5.0.0/lib/rails/commands.rb:18:in `' from bin/rails:9:in `require' from bin/rails:9:in `' 

如果我尝试访问公共工作表,它可以工作。 我已经尝试了很多,但无法弄清楚导致这种情况的原因。 最初我使用API​​ Key方法进行授权,但根据https://developers.google.com/api-client-library/ruby/auth/api-keys上的文档,它说

调用不访问私有用户数据的API时,可以使用简单的API密钥。 这些密钥用于validation您的应用程序以进行会计核算。 Google Developers Console文档还介绍了API密钥。

注意:如果确实需要访问私有用户数据,则必须使用OAuth 2.0。 有关详细信息,请参阅将OAuth 2.0用于Web服务器应用程序,将OAuth 2.0用于已安装的应用程序,以及将OAuth 2.0用于服务器到服务器应用程序。

因此我改用服务帐户方法。 但它没有帮助。

任何人都可以让我知道我错过了什么?

其他调查结果:

以下posthttps://stackoverflow.com/a/38530755/936494看起来很有帮助,但根据我的要求,我想避免使用3-legged oauth,原因是应该通过后台作业访问和更新工作表。

这已经解决了。 感谢Steve Bazyl(谷歌会员) ,他提供了以下有价值的建议,直接解决了这个问题:

您是否与服务帐户共享了表格? 服务帐户实际上是单独的用户,需要在ACL上与任何其他用户相同。

参考: https : //github.com/google/google-api-ruby-client/issues/461#issuecomment-243328234