You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ruby on Rails应用中无OOB_URI使用Google Sheets API?

解决Google Sheets API OOB流禁用问题(Ruby on Rails)

Google已全面禁用OOB(urn:ietf:wg:oauth:2.0:oob)授权流,以下是针对你的「永久访问、频繁调用API」需求的两种解决方案,优先推荐服务账号方案。


方案一:服务账号认证(推荐,无用户交互、永久访问)

服务账号是Google Cloud专为服务器端应用设计的认证方式,无需用户手动授权,令牌自动刷新,完美适配后台持续调用API的场景。

1. 配置服务账号

  • 登录Google Cloud Console,进入你的项目,前往「IAM与管理」→「服务账号」,创建新服务账号。
  • 生成密钥:在服务账号详情页的「密钥」标签下,点击「添加密钥」→「创建新密钥」,选择JSON格式,下载后保存到config/google_service_account_key.json。
  • 共享目标Google Sheet:将服务账号邮箱(密钥JSON中的client_email字段)添加为表格的「查看者」(如需编辑权限则设为「编辑者」)。

2. 修改代码

替换原有的authorize方法,改用服务账号认证:

require 'google/apis/sheets_v4'
require "googleauth"

APPLICATION_NAME = "Google Sheets API Ruby App".freeze
SERVICE_ACCOUNT_KEY_PATH = "config/google_service_account_key.json".freeze
SCOPE = Google::Apis::SheetsV4::AUTH_SPREADSHEETS_READONLY 

def authorize
  # 从服务账号密钥文件初始化认证
  credentials = Google::Auth::ServiceAccountCredentials.make_creds(
    json_key_io: File.open(SERVICE_ACCOUNT_KEY_PATH),
    scope: SCOPE
  )
  credentials.fetch_access_token!
  credentials
end

def datasheets
  service = Google::Apis::SheetsV4::SheetsService.new
  service.client_options.application_name = APPLICATION_NAME
  service.authorization = authorize

  spreadsheet_id = "你的目标表格ID"
  range = "Class Data!A2:E"
  response = service.get_spreadsheet_values spreadsheet_id, range
  
  puts "Name, Major:"
  response.values.empty? ? puts("No data found.") : response.values.each { |row| puts "#{row[0]}, #{row[4]}" }
end

3. Gemfile保持不变

gem 'googleauth'
gem 'google-api-client'
gem 'google-apis-sheets_v4'

方案二:用户授权替代流(需用户交互)

如果必须关联特定用户账号,可选择以下两种替代OOB的授权方式:

方式1:桌面应用(本地端口重定向)

  • 在Google Cloud Console的「API与服务」→「凭据」,创建「桌面应用」类型的OAuth客户端ID。
  • 修改授权逻辑,使用本地端口接收回调:
require 'google/apis/sheets_v4'
require "googleauth"
require "googleauth/stores/file_token_store"
require "webrick"

APPLICATION_NAME = "Google Sheets API Ruby Quickstart".freeze
CREDENTIALS_PATH = "config/google_sheets_credentials.json".freeze
TOKEN_PATH = "token.yaml".freeze
SCOPE = Google::Apis::SheetsV4::AUTH_SPREADSHEETS_READONLY 
REDIRECT_URI = "http://localhost:3000/oauth2callback"

def authorize
  client_id = Google::Auth::ClientId.from_file CREDENTIALS_PATH
  token_store = Google::Auth::Stores::FileTokenStore.new file: TOKEN_PATH
  authorizer = Google::Auth::UserAuthorizer.new client_id, SCOPE, token_store
  user_id = "default"
  credentials = authorizer.get_credentials user_id

  if credentials.nil?
    # 启动临时本地服务器接收授权码
    server = WEBrick::HTTPServer.new(Port: 3000, BindAddress: 'localhost')
    code = nil

    server.mount_proc '/oauth2callback' do |req, res|
      code = req.query['code']
      res.body = "授权成功!可以关闭此窗口。"
      server.shutdown
    end

    Thread.new { server.start }

    # 生成授权URL并提示用户打开
    url = authorizer.get_authorization_url(base_url: REDIRECT_URI)
    puts "请在浏览器中打开以下链接:\n#{url}"
    sleep until code

    credentials = authorizer.get_and_store_credentials_from_code(
      user_id: user_id, code: code, base_url: REDIRECT_URI
    )
  end
  credentials
end

方式2:Web应用(服务器端重定向)

针对Rails Web应用,创建「Web应用」类型的OAuth客户端ID,配置重定向URI为https://你的域名/oauth2callback,通过Rails路由处理回调并持久化令牌(如存入数据库)。


关键注意事项

  • 服务账号方案无需用户干预,令牌自动刷新,是满足「永久访问、频繁调用」需求的最优解。
  • 确保服务账号邮箱已被共享到目标Google Sheet,否则会触发权限不足错误。
  • 服务账号密钥文件包含敏感信息,需添加到.gitignore,禁止提交到版本控制。

内容的提问来源于stack exchange,提问作者Elise S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 02:57:47