使用Ruby调用Google Sheets API时服务账号认证报错:Expected top level property 'installed' or 'web'
解决服务账号认证适配Google Sheets API Ruby代码的问题
你的错误根源很明确:你使用的是服务账号的凭证文件,但快速入门代码是为OAuth 2.0桌面应用(installed类型凭证)编写的,两种凭证的JSON结构完全不同,所以代码会报错找不到installed或web顶级字段。
下面是针对服务账号的完整解决方案,替换原有的授权逻辑即可:
第一步:确保服务账号拥有Sheet访问权限
先打开你要访问的Google Sheet,点击右上角的「分享」按钮,把服务账号的邮箱地址(可以在你的credentials.json文件里找到client_email字段)添加进去,赋予对应的权限(比如「查看者」或「编辑者」,根据你的业务需求选择)。
第二步:修改Ruby代码适配服务账号认证
替换原有的authorize方法,改用服务账号的JWT认证方式,完整代码如下:
require "google/apis/sheets_v4" require "googleauth" APPLICATION_NAME = "Google Sheets API Ruby Service Account Quickstart".freeze CREDENTIALS_PATH = "credentials.json".freeze # 按需修改作用域:只读用AUTH_SPREADSHEETS_READONLY,读写用AUTH_SPREADSHEETS SCOPE = Google::Apis::SheetsV4::AUTH_SPREADSHEETS_READONLY ## # 使用服务账号凭证获取授权 # @return [Google::Auth::ServiceAccountCredentials] 服务账号OAuth2凭证 def authorize # 从服务账号凭证文件加载认证信息 credentials = Google::Auth::ServiceAccountCredentials.make_creds( json_key_io: File.open(CREDENTIALS_PATH), scope: SCOPE ) credentials.fetch_access_token! credentials end # 初始化API服务 service = Google::Apis::SheetsV4::SheetsService.new service.client_options.application_name = APPLICATION_NAME service.authorization = authorize # 读取示例Sheet数据(替换成你自己的spreadsheet_id和range) spreadsheet_id = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms" range = "Class Data!A2:E" response = service.get_spreadsheet_values spreadsheet_id, range puts "Name, Major:" if response.values.empty? puts "No data found." else response.values.each do |row| puts "#{row[0]}, #{row[4]}" end end
关键修改说明:
- 移除了
googleauth/stores/file_token_store相关依赖,因为服务账号不需要持久化用户令牌 - 使用
Google::Auth::ServiceAccountCredentials.make_creds加载服务账号凭证,而不是原来的UserAuthorizer流程 - 调用
fetch_access_token!获取临时访问令牌(服务账号会自动处理令牌刷新)
额外注意事项
- 确保
credentials.json文件路径正确,或者直接把文件放在代码运行的同目录下 - 如果需要修改Sheet数据,记得把
SCOPE改成Google::Apis::SheetsV4::AUTH_SPREADSHEETS,同时服务账号需要有Sheet的编辑权限 - 服务账号认证适合无用户交互的后台脚本/服务,不需要手动打开浏览器授权,这和快速入门的OAuth流程(需要用户手动授权)是两种完全不同的认证模式
内容的提问来源于stack exchange,提问作者Felipe Cristiano
相关产品推荐
相关产品推荐

