关于 google-auth
面向 Node.js 和 Python 开发者的 Google 身份验证实践指南,涵盖多种凭据与授权流程,并强调凭据保护和安全配置。
主要功能
- 01ADC 与服务账号认证
- 02OAuth 2.0 用户授权流程
- 03Google ID 令牌验证
- 04JWT、API 密钥与计算凭据
- 05Workload Identity Federation
- 06令牌刷新与安全实践
适用场景
- 01为服务器配置 Google API 访问
- 02实现代表用户授权的 OAuth 流程
- 03验证 Google 登录返回的 ID 令牌
- 04在 AWS、Azure 或 OIDC 环境联合身份
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ssheleg/ sheleg-dev --skill google-auth安装后在 Claude Code 中输入/google-auth确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/adc-and-service-accounts.mdoauth2-web-server.mdsign-in-with-google.mdworkload-identity.md详细介绍
Node.js 和 Python 的 Google 身份验证
库
Node.js
google-auth-library— 核心身份验证库(OAuth2Client、GoogleAuth、JWT、Compute、Impersonated)googleapis— Google API 客户端(封装 google-auth-library)
npm install google-auth-library
npm install googleapis
以下 client.fetch() 调用需要 google-auth-library ≥ 10.1.0(兼容 fetch 的 API 于 10.1.0 中引入,日期为 2025-06-12);在 9.x 中使用参数相同的 client.request()。截至 2026-08-31 的检查结果:最新版本为 11.x,且保留了这两种方法。
Python
google-auth— 核心身份验证库(google.oauth2、google.auth、credentials、transport)google-auth-oauthlib— OAuth 2.0 用户凭据流程辅助工具(Flow、InstalledAppFlow)google-api-python-client— Google API 客户端(封装 google-auth)
pip install google-auth
pip install google-auth-oauthlib
pip install google-api-python-client
身份验证方法概览
| 方法 | 使用场景 | Node.js 关键类 | Python 关键模块 / 类 |
|---|---|---|---|
| ADC | 所有用户使用相同身份,服务到服务 | GoogleAuth | google.auth.default() |
| OAuth 2.0 | 代表最终用户执行操作 | OAuth2Client | google_auth_oauthlib.flow.Flow |
| Sign In with Google (GIS) | 网站上的用户登录/注册 — google-signin 技能的依据 | GIS JS SDK + verifyIdToken() | GIS JS SDK + id_token.verify_oauth2_token() |
| JWT / Service Account | 服务到服务,单一身份 | JWT | service_account.Credentials |
| API Key | 公开数据,无用户上下文 | OAuth2Client({ apiKey }) | 传入 googleapiclient.discovery.build(developerKey=) |
| Compute | 在附加了服务账号的 GCP 上 | Compute | google.auth.compute_engine.Credentials |
| Workload Identity Federation | AWS/Azure/OIDC → GCP,无需 SA 密钥 | ExternalAccountClient | google.auth.identity_pool.Credentials / google.auth.aws.Credentials |
快速模式
1. 应用默认凭据(ADC)
Node.js
const {GoogleAuth} = require('google-auth-library');
const auth = new GoogleAuth({
scopes: 'https://www.googleapis.com/auth/cloud-platform'
});
const client = await auth.getClient();
const res = await client.fetch('https://dns.googleapis.com/dns/v1/projects/...');
Python
import google.auth
import google.auth.transport.requests
credentials, project = google.auth.default(
scopes=['https://www.googleapis.com/auth/cloud-platform']
)
request = google.auth.transport.requests.Request()
credentials.refresh(request)
ADC 搜索顺序(环境变量优先——此行之前的顺序写反了):GOOGLE_APPLICATION_CREDENTIALS 环境变量 → gcloud auth application-default login 文件 → 附加的服务账号(元数据)。配置前打印解析后的主体和来源(不含机密)——如果同时存在多个来源,只有解析出的来源名称能说明你实际使用的是哪一个。
如需详细了解 ADC 设置和服务账号用法,请参阅 references/adc-and-service-accounts.md。
2. OAuth 2.0 Web 服务器流程
Node.js
const {OAuth2Client} = require('google-auth-library');
const client = new OAuth2Client({
clientId: CLIENT_ID,
clientSecret: CLIENT_SECRET,
redirectUri: REDIRECT_URI
});
const authUrl = client.generateAuthUrl({
access_type: 'offline',
scope: ['https://www.googleapis.com/auth/userinfo.profile'],
state: crypto.randomBytes(32).toString('hex'),
include_granted_scopes: true
});
// After redirect: exchange code for tokens
const {tokens} = await client.getToken(code);
client.setCredentials(tokens);
Python
from google_auth_oauthlib.flow import Flow
flow = Flow.from_client_secrets_file(
'client_secret.json',
scopes=['https://www.googleapis.com/auth/userinfo.profile'],
redirect_uri=REDIRECT_URI
)
authorization_url, state = flow.authorization_url(
access_type='offline',
include_granted_scopes='true'
)
# After redirect: exchange code for tokens
flow.fetch_token(code=code)
credentials = flow.credentials
refresh_token 仅在首次授权时返回。使用 prompt: 'consent'(Node.js)或 prompt='consent'(Python)强制重新征求同意。
如需了解完整的 OAuth 2.0 流程(参数、令牌交换、刷新、撤销、增量授权),请参阅 references/oauth2-web-server.md。
3. 验证 Google ID Token——库调用
Node.js
const {OAuth2Client} = require('google-auth-library');
const client = new OAuth2Client();
const ticket = await client.verifyIdToken({
idToken: token,
audience: WEB_CLIENT_ID,
});
const payload = ticket.getPayload();
Python
from google.oauth2 import id_token
from google.auth.transport import requests
payload = id_token.verify_oauth2_token(token, requests.Request(), WEB_CLIENT_ID)
此调用会检查签名、aud、exp 和 iss,除此之外不做任何检查。这是库的约定,并非网页登录的约定:如需了解登录安全检查清单(nonce 绑定、email_verified、登录 CSRF 防护、账号关联),请使用 google-signin 技能——该技能是此约定的唯一权威来源,本技能特意不重复说明。
4. JWT / Service Account
Node.js
const {JWT} = require('google-auth-library');
const keys = require('./service-account-key.json');
const client = new JWT({
email: keys.client_email,
key: keys.private_key,
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
});
const res = await client.fetch(url);
Python
from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file(
'service-account-key.json',
scopes=['https://www.googleapis.com/auth/cloud-platform']
)
# Or from a dict already loaded into memory:
credentials = service_account.Credentials.from_service_account_info(
info,
scopes=['https://www.googleapis.com/auth/cloud-platform']
)
5. API Key
Node.js
const {OAuth2Client} = require('google-auth-library');
const client = new OAuth2Client({ apiKey: 'my-api-key' });
// Or via GoogleAuth:
const {GoogleAuth} = require('google-auth-library');
const auth = new GoogleAuth({
clientOptions: { apiKey: 'my-api-key' }
});
Python
from googleapiclient.discovery import build
service = build('customsearch', 'v1', developerKey='my-api-key')
6. 令牌刷新
Node.js
client.on('tokens', (tokens) => {
if (tokens.refresh_token) {
// Store refresh_token — only sent on first auth
}
// Record an event name only; token values never enter logs.
console.info("google_auth_tokens_refreshed");
});
Python
from google.auth.transport.requests import Request
if credentials.expired and credentials.refresh_token:
credentials.refresh(Request())
# credentials.token is the new access token
# credentials.expiry is the new expiration datetime
安全最佳实践
- 切勿在客户端代码中暴露
client_secret或服务账号密钥 - 在 OAuth 流程中,务必验证
state参数,以防止 CSRF - 将
sub(而非email)用作 Google ID 令牌中的唯一用户标识符 - 安全存储
refresh_token;它仅在首次授权时返回 - 使用前验证外部凭据配置(检查
token_url、service_account_impersonation_url是否指向 googleapis.com) - 在非 GCP 环境中,优先使用 Workload Identity Federation,而非服务账号密钥
- 对于最终用户网页登录,请应用 google-signin 技能的完整检查清单——此处只复述部分内容,正是这两项技能此前产生分歧的原因
- 生产环境缺少密钥时必须拒绝启动。 会话签名密钥和任何凭据存储密钥在生产环境中都是必需的,且不得使用开发环境备用值——硬编码的默认值会让每个部署都用仓库中的密钥签署 Cookie。缺少密钥 → 拒绝启动,绝不发出警告后继续运行(DV-07)。
- 日志必须经过清理;凭据绝不能进入日志。 令牌、
client_secret、refresh_token、会话值都不得出现在日志行、堆栈跟踪或错误消息中——令牌一旦进入日志,任何有权访问日志的人就能获得该令牌。应通过允许列表进行脱敏,而不是试图从日志中剔除密钥。 - 必须使用 HTTPS,且凭据存储操作可能失败。 身份验证 Cookie 必须设置
Secure,回调必须拒绝纯 HTTP(通过http://传输的 OAuth 授权码会暴露在传输线路上);凭据存储读取或写入失败即表示身份验证失败——应重新提示或返回 503,绝不能假定凭据已加载并继续。 - Python 特有要求:在多次验证之间复用同一个
google.auth.transport.requests.Request()实例,以便使用连接池;在高频路径中不要每次调用都新建实例
参考文件
- OAuth 2.0 Web Server Flow — 完整的 OAuth 2.0 流程:参数、授权同意、令牌交换、刷新、撤销、增量授权、错误处理(Node.js + Python)
- ADC & Service Accounts — Application Default Credentials 设置、服务账号密钥、JWT、Compute 凭据、环境配置(Node.js + Python)
- Sign In with Google — Google Identity Services(GIS)、ID 令牌验证、CSRF 防护、One Tap、FedCM(Node.js + Python)
- Workload Identity Federation — AWS、Azure、OIDC/SAML 联合、劳动力身份、可执行文件来源的凭据(Node.js + Python)
降级处理
- 不是 Claude Code(Cursor、Codex、skills CLI、API 容器):此工具包的
PreToolUse门禁不会运行;没有任何机制会拒绝有效凭据,只有你自己会拒绝。 - 通过复制而非作为插件安装:规范仍然适用,但没有
hooks/。 - 没有浏览器或无法访问控制台:授权同意屏幕和客户端 ID 的配置需要人工完成。请指出具体的屏幕及受阻事项,完成代码部分,并且不要反复尝试只有人才能完成的登录。
触发词
更多会将请求路由到此处的表达:"OAuth 2.0 Google"、"Application Default Credentials"、 "Workload Identity Federation"、"Google ID token"、"GOOGLE_APPLICATION_CREDENTIALS"、"Google SSO"、"服务账号密钥"、"验证 ID 令牌"。
从 0.16.2 版描述中移至此处:"Google 授权"。