Skip to content

Proposal: Google OAuth token exchange endpoint (POST /api/v1/auth/oauth/google) #218

Description

@kcrmin

Why

The product wants Google sign-in on /login and /signup. The frontend side is implemented behind an honesty gate (ui GoogleSignInButton): the button renders only when VITE_GOOGLE_OAUTH_CLIENT_ID is configured AND the account client implements the exchange — so nothing user-visible exists until this endpoint does.

The current identity API (spec bef4de6) has no social/OAuth surface; identity is email+password with email verification.

Proposed contract

POST /api/v1/auth/oauth/google — 공개, 200

Request:

{ "idToken": "(Google ID token JWT from Google Identity Services)", "deviceLabel": "Web browser" }

Response: identical to LoginResponseaccountId, sessionId, sessionToken, expiresAt — so the session semantics (rotation, logout, expiry) stay one system.

Server responsibilities:

  • Verify the ID token signature against Google JWKS, aud = our OAuth client id, iss = accounts.google.com, exp.
  • Require email_verified: true; treat Google-verified email as satisfying our email-verification step.
  • First sight of a Google subject: create the account (email from token), record the social identity linkage (new table, forward-only migration); afterwards: log the linked account in.
  • Same session issuance path as password login (session token, expiry, device label).
  • 401 with a stable code (e.g. GOOGLE_TOKEN_REJECTED) for invalid/expired tokens; correlation id as elsewhere.

Notes

  • This is an identity-domain (A) product change: account provisioning without a password touches db/schema.dbml (identity tables) and possibly identity specs — flagging rather than implementing past the authority gate.
  • Frontend reference: ui src/api/account.ts loginWithGoogle, src/components/GoogleSignInButton.tsx.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions