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

使用GoogleAuth无文件存储认证遇from_hash报错,求解决方案

Fixing Google::Auth::ClientId.from_hash Error & Using Environment Variables

Let's break down your problem and solve it step by step:

Why the from_hash Call is Failing

The error message says it can't find the top-level 'installed' or 'web' property, but your hash clearly has :installed — here's the catch:
The from_hash method in the googleauth gem expects string keys (like "installed"), not symbol keys (:installed). When you load credentials via from_file, the JSON parser automatically converts keys to strings, which works seamlessly. But when you manually create a hash with symbols, the method can't locate the required top-level keys it's looking for.

Quick Verification Test

You can confirm this in pry right away:

# This will throw the same error (symbol keys)
creds_sym = {:installed=> {:client_id=>"[redacted]", ...}}
Google::Auth::ClientId.from_hash(creds_sym)

# This will work as expected (string keys)
creds_str = {"installed"=> {:client_id=>"[redacted]", ...}}
Google::Auth::ClientId.from_hash(creds_str)

Solution 1: Fix the Hash Key Format

If you're building the hash manually, convert all top-level keys to strings. If you're pulling the content from a JSON source (like an environment variable), parse it properly to get string keys automatically:

require 'json'

# Example: Parsing JSON content from a variable
creds_json = '{"installed":{"client_id":"YOUR_ID", ...}}'
creds_hash = JSON.parse(creds_json) # This outputs a hash with string keys
client_id = Google::Auth::ClientId.from_hash(creds_hash)

Solution 2: Store Credentials in Environment Variables (Deployment-Friendly)

To avoid storing sensitive info in files, you can use environment variables in two practical ways:

Option A: Full Credentials JSON in One Env Var

  1. Set the environment variable (in your .env file, server config, or deployment tool):
    GOOGLE_CREDENTIALS='{"installed":{"client_id":"YOUR_CLIENT_ID","project_id":"YOUR_PROJECT","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"YOUR_SECRET","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}'
    
  2. In your Ruby code:
    require 'json'
    
    creds_hash = JSON.parse(ENV['GOOGLE_CREDENTIALS'])
    client_id = Google::Auth::ClientId.from_hash(creds_hash)
    

Option B: Split Credentials into Individual Env Vars

If you prefer granular control over each credential field:

  1. Set separate environment variables:
    GOOGLE_CLIENT_ID="YOUR_CLIENT_ID"
    GOOGLE_CLIENT_SECRET="YOUR_SECRET"
    GOOGLE_AUTH_URI="https://accounts.google.com/o/oauth2/auth"
    GOOGLE_TOKEN_URI="https://oauth2.googleapis.com/token"
    GOOGLE_CERT_URL="https://www.googleapis.com/oauth2/v1/certs"
    
  2. Build the required hash manually with string keys:
    creds_hash = {
      "installed" => {
        "client_id" => ENV['GOOGLE_CLIENT_ID'],
        "client_secret" => ENV['GOOGLE_CLIENT_SECRET'],
        "auth_uri" => ENV['GOOGLE_AUTH_URI'],
        "token_uri" => ENV['GOOGLE_TOKEN_URI'],
        "auth_provider_x509_cert_url" => ENV['GOOGLE_CERT_URL'],
        "redirect_uris" => ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"]
      }
    }
    client_id = Google::Auth::ClientId.from_hash(creds_hash)
    

Quick Note on Gem Version

You're using googleauth 0.12.0 — this key-type behavior is consistent across recent versions, but if you run into further issues, double-check that your gem version aligns with the code patterns you're using.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:17:32