mcpField
G
google-auth

google-auth

github.com/ssheleg安全4225 次安装2 天前更新
代码仓库

关于 google-auth

面向 Node.js 和 Python 开发者的 Google 身份验证实践指南,涵盖多种凭据与授权流程,并强调凭据保护和安全配置。

主要功能

  1. 01ADC 与服务账号认证
  2. 02OAuth 2.0 用户授权流程
  3. 03Google ID 令牌验证
  4. 04JWT、API 密钥与计算凭据
  5. 05Workload Identity Federation
  6. 06令牌刷新与安全实践

适用场景

  1. 01为服务器配置 Google API 访问
  2. 02实现代表用户授权的 OAuth 流程
  3. 03验证 Google 登录返回的 ID 令牌
  4. 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.md
oauth2-web-server.md
sign-in-with-google.md
workload-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所有用户使用相同身份,服务到服务GoogleAuthgoogle.auth.default()
OAuth 2.0代表最终用户执行操作OAuth2Clientgoogle_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服务到服务,单一身份JWTservice_account.Credentials
API Key公开数据,无用户上下文OAuth2Client({ apiKey })传入 googleapiclient.discovery.build(developerKey=)
Compute在附加了服务账号的 GCP 上Computegoogle.auth.compute_engine.Credentials
Workload Identity FederationAWS/Azure/OIDC → GCP,无需 SA 密钥ExternalAccountClientgoogle.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 授权"。

评论

支持 Markdown