Files
frontend/specs/001-google-oauth-auth/quickstart.md
Andre 130f35c4f8 feat: implement Google OAuth authentication
- Add Google OAuth 2.0 login flow with passport-google-oauth20
- Create User and RefreshToken entities for session management
- Implement JWT access tokens (15min) + HttpOnly refresh cookies (7 days)
- Add auth endpoints: /google, /google/callback, /refresh, /me, /logout
- Create LoginPage with Google sign-in button (shadcn/ui)
- Add AuthGuard for protected routes with redirect preservation
- Implement silent token refresh on app mount
- Add UserMenu component with avatar and sign-out

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 13:05:18 -03:00

3.4 KiB

Quickstart: Google OAuth Authentication

Feature: 001-google-oauth-auth Date: 2026-01-29

Prerequisites

  1. Google Cloud Console Setup

    • Create a project at https://console.cloud.google.com
    • Enable "Google+ API" or "Google Identity" API
    • Configure OAuth consent screen (External, if not Google Workspace)
    • Create OAuth 2.0 credentials (Web application type)
    • Add authorized redirect URI: http://localhost:3000/api/auth/google/callback
  2. Environment Variables Add to backend/.env:

    # Google OAuth
    GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
    GOOGLE_CLIENT_SECRET=your-client-secret
    GOOGLE_CALLBACK_URL=http://localhost:3000/api/auth/google/callback
    
    # JWT Configuration
    JWT_SECRET=your-secure-random-secret-min-32-chars
    JWT_ACCESS_EXPIRATION=15m
    JWT_REFRESH_EXPIRATION=7d
    
    # Frontend URL (for redirects)
    FRONTEND_URL=http://localhost:5173
    

Installation

Backend Dependencies

cd backend
npm install @nestjs/passport @nestjs/jwt passport passport-google-oauth20 bcrypt
npm install -D @types/passport-google-oauth20 @types/bcrypt

Frontend Dependencies

No additional dependencies required. Uses existing:

  • react-router-dom (routing)
  • zustand (auth state)
  • axios (API calls)
  • shadcn/ui (UI components)

Database Migration

Create and run migration for new tables:

cd backend
npm run typeorm:generate -- -n CreateAuthTables
npm run typeorm:run

Tables created:

  • users (id, googleId, email, displayName, avatarUrl, createdAt, lastLoginAt)
  • refresh_tokens (id, userId, token, expiresAt, createdAt, revokedAt)

Quick Test Flow

  1. Start the backend:

    cd backend && npm run start:dev
    
  2. Start the frontend:

    cd frontend && npm run dev
    
  3. Test OAuth flow:

    • Navigate to http://localhost:5173/tool
    • Should redirect to login page
    • Click "Sign in with Google"
    • Complete Google consent
    • Should redirect back to /tool with active session
  4. Verify session persistence:

    • Refresh the page
    • Should remain on /tool without re-authenticating
  5. Test sign out:

    • Click user menu → Sign out
    • Should redirect to login page
    • Navigating to /tool should redirect to login

API Endpoints

Method Path Description
GET /api/auth/google Initiate OAuth (browser redirect)
GET /api/auth/google/callback OAuth callback handler
POST /api/auth/refresh Refresh access token
GET /api/auth/me Get current user (requires auth)
POST /api/auth/logout Sign out (requires auth)

Frontend Routes

Path Component Protected
/ LandingPage No
/login LoginPage No
/auth/callback AuthCallbackPage No
/tool ToolPage Yes

Troubleshooting

"redirect_uri_mismatch" error:

  • Ensure callback URL in Google Console matches GOOGLE_CALLBACK_URL exactly
  • Include protocol (http/https) and port

"Invalid token" after refresh:

  • Check JWT_SECRET is set and consistent
  • Verify refresh token cookie is being sent (check browser DevTools)

CORS errors:

  • Ensure FRONTEND_URL matches exactly (including port)
  • Check credentials: true in CORS config

Session not persisting:

  • Verify httpOnly cookie is set (check Application → Cookies in DevTools)
  • Check sameSite and secure settings match environment