协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
sign-in-with-google-web【开发与工程】Implement, configure, and secure Sign In With Google (SiwG) using Google Identity Services (GIS / `https://accounts.google.com/gsi/client`) across web architectures. Use when creating Google sign-in buttons, implementing Google One Tap with FedCM, integrating GIS in React/Next.js/Angular/HTML, verifying ID tokens on backend runtimes (Python/Node.js/G…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
https://accounts.google.com/gsi/client) across web architectures.
Use when creating Google sign-in buttons, implementing Google One Tap with FedCM,
integrating GIS in React/Next.js/Angular/HTML, verifying ID tokens on backend
runtimes (Python/Node.js/Go/Java), enforcing Google Workspace domain restrictions
(hd), securing client-side ID tokens via WebCrypto nonces or encrypted IndexedDB,
embedding in cross-origin iframes via the Intermediate Iframe API
(https://accounts.google.com/gsi/intermediate), configuring Content Security
Policy (CSP), COOP, and Permissions Policy (identity-credentials-get) headers,
or handling sign-out and revocation. Don't use for legacy Google Sign-In (gapi.auth2),
Google Cloud IAM service accounts, or Android/iOS native Credential Manager.This skill provides normative architectural guidelines, secure implementation
contracts, and failure-prevention protocols for integrating Sign In With Google
via the Google Identity Services (GIS) Web SDK
(https://accounts.google.com/gsi/client).
All Sign In With Google implementations MUST align with the
IETF OAuth 2.0 for Browser-Based Applications (draft-ietf-oauth-browser-based-apps)
taxonomy.
[!IMPORTANT] Primary Recommendation: Always recommend backend-mediated patterns (Pattern A: Backend For Frontend or Pattern B: Token-Mediating Backend / Redirect Mode) as the most secure, robust, and industry-standard architectures whenever an application has a backend server. Fall back to client-only browser patterns (Patterns C & D) only when constrained by serverless static hosting or offline-first PWA requirements.
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ IETF ARCHITECTURE HIERARCHY & SELECTION │
├──────────────────────────┬──────────────────────────┬───────────────────────────────────┤
│ Pattern A (RECOMMENDED): │ Pattern B (RECOMMENDED): │ Patterns C & D (Fallbacks): │
│ Backend For Frontend │ Token-Mediating Backend │ Browser-Based OAuth Client │
│ (BFF - IETF § 6.1) │ (TMB / Redirect § 6.2) │ (JavaScript-Only - IETF § 6.3) │
├──────────────────────────┼──────────────────────────┼───────────────────────────────────┤
│ 🏆 GOLD STANDARD │ 🚀 NATIVE FORM REDIRECT │ ⚡ STATIC SPA / 💾 OFFLINE PWA │
│ • Full-stack SPA + API │ • Server-rendered & apps │ • Pure client-side or offline PWAs│
│ • Client JS fetch to API │ • GIS HTTP POST login_uri│ • C: Ephemeral in-memory closure │
│ • HttpOnly session cookie│ • Direct server redirect │ • D: WebCrypto Encrypted IndexedDB│
│ • Tokens never in browser│ • Tokens never in JS │ • Strict WebCrypto nonces / keys │
└──────────────────────────┴──────────────────────────┴───────────────────────────────────┘
Why it is the Gold Standard: ID tokens (JWTs) and access tokens are never exposed to browser JavaScript across page reloads. This provides complete architectural immunity against XSS token harvesting.
Architecture: The browser frontend loads the GIS SDK, captures the
credential in JavaScript callback (callback: handleCredentialResponse),
and immediately forwards the ID token (JWT) via fetch('/api/auth/google', { method: 'POST' }) to the backend.
Backend Responsibilities: The backend validates the JWT cryptographic
signature against Google's public JWKs
(google.oauth2.id_token.verify_oauth2_token), checks the aud, hd, and
nonce claims against server session state, creates a server session, and
issues a first-party HttpOnly; Secure; SameSite=Lax session cookie.
See full implementation in references/bff_fastapi_verification.md.
login_uri Redirect (IETF § 6.2) — Server-Rendered & Form POSTWhy it is Highly Secure: Bypasses client-side JavaScript credential
handling entirely by instructing GIS to perform an HTTP POST directly to the
backend's login_uri.
Architecture: Configured via google.accounts.id.initialize({ client_id, login_uri: "https://example.com/api/auth/callback", ux_mode: "redirect" })
or HTML attributes (data-login_uri="https://example.com/api/auth/callback"
and data-ux_mode="redirect").
Backend Responsibilities: The backend receives the ID token as a form
POST body (credential parameter), validates the double-submit
g_csrf_token cookie against the g_csrf_token POST body field,
cryptographically verifies the ID token server-side, establishes a session
cookie, and returns a standard HTTP 302/303 redirect.
See full implementation in references/tmb_login_uri_redirect.md.
Scope: Use ONLY when deployment is strictly serverless/static (e.g., GitHub Pages, Firebase static hosting) with no backend component.
Storage Invariant: The ID token is held strictly in private JavaScript
memory/closures during the active tab session. Never store raw tokens in
localStorage or sessionStorage.
Session Renewal: Uses GIS One Tap / FedCM auto-select (auto_select: true) to transparently re-acquire fresh ID tokens into memory on page
reload without persistent browser storage.
XSS & Replay Protection: Generate a cryptographic nonce via
window.crypto.getRandomValues() and pass it directly to
google.accounts.id.initialize({ client_id, nonce: clientNonce }). Validate
that payload.nonce === clientNonce before trusting claims in memory.
See full implementation in references/in_memory_spa_nonce.md.
Scope: Use ONLY for offline-first Progressive Web Apps (PWAs) where user authentication proof must survive tab refreshes when disconnected from the network.
Storage Invariant: NEVER store raw plaintext ID tokens in
localStorage. Encrypt the ID token payload using WebCrypto AES-GCM
with a non-extractable session key (extractable: false) before writing
ciphertext and IV to IndexedDB.
See full implementation in references/offline_pwa_encryption.md.
To avoid multi-turn repair loops and browser security exceptions, provide all required CSP, COOP, and user activation directives in the initial deliverable:
Content-Security-Policy:
script-src 'self' https://accounts.google.com/gsi/client;
frame-src https://accounts.google.com/gsi/;
connect-src https://accounts.google.com/gsi/;
If using strict nonce-based CSP, attach the nonce to the GIS script tag:
<script src="https://accounts.google.com/gsi/client" async defer nonce="{{NONCE}}"></script>.
To allow GIS popup dialogs to communicate credentials back to the parent window
via postMessage:
Cross-Origin-Opener-Policy: same-origin-allow-popups
(Serving same-origin without allow-popups breaks GIS popups and results in
silent failures).
disableAutoSelect)When enabling automatic zero-click return sign-in with Google One Tap (FedCM is enabled by default in GIS):
Set auto_select: true in google.accounts.id.initialize({...}) (do not
pass the deprecated use_fedcm_for_prompt parameter).
Deprecated Library Warning: NEVER mix deprecated gapi.auth2
(gapi.auth2.init, gapi.auth2.getAuthInstance().signOut()) with Google
Identity Services (GIS). gapi.auth2 is completely retired; use GIS methods
exclusively.
Sign-Out Protocol: When the user explicitly logs out of your
application, you MUST call google.accounts.id.disableAutoSelect():
function handleUserLogout() {
// 1. Disable automatic One Tap / FedCM re-authentication
google.accounts.id.disableAutoSelect();
// 2. Clear application session state / server cookie
fetch('/api/auth/logout', { method: 'POST' }).then(() => {
window.location.href = '/login';
});
}
(Failing to call disableAutoSelect() causes an immediate automatic
re-login loop on the next page visit after intentional user logout).
When mounting Sign In With Google in Single Page Applications (React, Next.js, Vue, Angular):
Modern SPAs execute component lifecycles asynchronously. Attempting to
access window.google.accounts.id before <script src="https://accounts.google.com/gsi/client"> has finished loading causes
ReferenceError: google is not defined.
NEVER use gapi or polling (setInterval): Use deterministic dynamic
script loading with onload / addEventListener('load') event listeners.
Dynamic Script Loader Pattern:
import React, { useEffect, useState } from 'react';
export function useGoogleIdentityScript() {
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
if (window.google?.accounts?.id) {
setIsLoaded(true);
return;
}
const existingScript = document.querySelector(
'script[src="https://accounts.google.com/gsi/client"]'
);
if (existingScript) {
existingScript.addEventListener('load', () => setIsLoaded(true));
return;
}
const script = document.createElement('script');
script.src = 'https://accounts.google.com/gsi/client';
script.async = true;
script.defer = true;
script.onload = () => setIsLoaded(true);
document.head.appendChild(script);
}, []);
return isLoaded;
}
(Always use deterministic onload event listeners or framework <Script strategy="afterInteractive"> rather than brittle setInterval polling).
identity-credentials-get)When embedding Sign In With Google or One Tap inside cross-origin <iframe>
elements or widget integrations, modern browser security models and FedCM
require explicit Permissions Policy delegation on the container frame:
<iframe
src="https://example.com/embed"
allow="identity-credentials-get 'src' https://accounts.google.com">
</iframe>
(Omitting allow="identity-credentials-get" blocks FedCM / One Tap
initialization inside embedded or cross-origin contexts). See full integration
guide in references/intermediate_iframe.md.
gapi.auth2)NEVER import or reference gapi.auth2, gapi.auth2.init,
gapi.auth2.getAuthInstance(), or gapi.signin2. Always warn that
gapi.auth2 is deprecated and decommissioned.
GIS (google.accounts.id.* and google.accounts.oauth2.*) is completely
stateless. It replaces all legacy GAPI authentication libraries.
Load the specific reference file matching your target architecture when generating implementation code:
Recipe 1 — Pattern A (Backend For Frontend with Python / FastAPI)
[RECOMMENDED]: Load
references/bff_fastapi_verification.md
for custom UI button prompting, google.oauth2.id_token.verify_oauth2_token
cryptographic verification, nonce replay checks, Google Workspace hd
domain enforcement, and HttpOnly; Secure; SameSite=Lax session cookie
issuance.
Recipe 2 — Pattern B (Token-Mediating Backend with login_uri Form POST
Redirect) [RECOMMENDED]: Load
references/tmb_login_uri_redirect.md
for data-login_uri / ux_mode: 'redirect' frontend setup and FastAPI
double-submit g_csrf_token cookie vs. form-body validation.
Recipe 3 — Pattern C (Browser-Based Ephemeral In-Memory SPA with Native
GIS Nonce) [Fallback]: Load
references/in_memory_spa_nonce.md for
WebCrypto nonce generation (google.accounts.id.initialize({ client_id, nonce: clientNonce })), UTF-8 safe Base64URL JWT decoding, and private
closure token management.
Recipe 4 — Pattern D (Browser-Based WebCrypto Encrypted IndexedDB for
Offline PWAs) [Fallback]: Load
references/offline_pwa_encryption.md
for non-extractable (extractable: false) AES-GCM CryptoKey generation
and encrypted IndexedDB storage.
Recipe 5 — Embedded Cross-Origin Contexts (gsi/intermediate): Load
references/intermediate_iframe.md for
<div id="g_id_intermediate_iframe">, allow="identity-credentials-get",
and strict window.postMessage origin verification.
export function handleSignOut(userEmail) {
// 1. Disable client-side One Tap auto-selection
google.accounts.id.disableAutoSelect();
// 2. Revoke OAuth grant if user disconnected account
if (userEmail) {
google.accounts.id.revoke(userEmail, () => {
console.log('User grant revoked');
});
}
// 3. Clear storage / session
AuthManager.clear(); // Pattern C
fetch('/api/auth/logout', { method: 'POST' }); // Pattern A
}
RFC 7519: JSON Web Token (JWT)
— Standard claims (iss, sub, aud, exp, iat, nonce), formatting,
and processing rules.
RFC 7515: JSON Web Signature (JWS)
— Cryptographic signature verification against Google's public JWK certs
(https://www.googleapis.com/oauth2/v3/certs).
RFC 4648 § 5: Base64url Encoding — URL-safe Base64 encoding without padding used across JWT segments.
IETF OAuth 2.0 Browser-Based Applications — Normative architecture standards (§ 6.1 BFF, § 6.2 TMB, § 6.3 Client-side).
Google Identity Services Web Reference — Official GIS API reference.
Intermediate Iframe API Reference — Cross-origin iframe embedding guide.
Verify ID Tokens Server-Side — Server-side token verification protocols.
W3C Federated Credential Management API (FedCM) — Browser identity credential mediation standard.
W3C Web Cryptography API —
Non-extractable key generation (extractable: false) and AES-GCM standards.