Files
frontend/specs/001-google-oauth-auth/research.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

115 lines
3.9 KiB
Markdown

# Research: Google OAuth Authentication
**Feature**: 001-google-oauth-auth
**Date**: 2026-01-29
## 1. NestJS Passport Google OAuth Setup
**Decision**: Use `@nestjs/passport` with `passport-google-oauth20` strategy
**Rationale**:
- Official NestJS integration provides decorator-based guards and strategies
- `passport-google-oauth20` is the actively maintained Google OAuth package
- Seamless integration with NestJS dependency injection and module system
- Built-in validate method simplifies user profile handling
**Alternatives Considered**:
- `passport-google-oauth2`: Older package, less TypeScript support
- Custom OAuth implementation: Too much boilerplate, harder to maintain
## 2. Authentication Strategy for SPAs
**Decision**: Hybrid approach - JWT access tokens (short-lived, in-memory) + HttpOnly cookie refresh tokens (7-day)
**Rationale**:
- Access tokens in memory provide stateless, scalable API authentication
- HttpOnly refresh tokens prevent XSS attacks while enabling token rotation
- Best balance between security, UX, and distributed system requirements
- Industry standard for modern SPAs
**Alternatives Considered**:
- Pure JWT (stateless): Can't invalidate tokens on logout/compromise
- Pure sessions: Doesn't scale well, requires sticky sessions
- localStorage for tokens: Vulnerable to XSS attacks
## 3. Token Storage in React
**Decision**: Access tokens in Zustand store (memory), refresh tokens in HttpOnly cookies
**Rationale**:
- HttpOnly cookies are inaccessible to JavaScript, preventing XSS token theft
- In-memory storage for short-lived access tokens (15-30 min)
- CSRF protection via `sameSite: 'strict'` and CORS configuration
- Silent refresh mechanism restores access token on page reload
**Alternatives Considered**:
- localStorage: Vulnerable to XSS attacks
- sessionStorage: Data lost on tab close, still XSS vulnerable
## 4. React Router Protected Routes
**Decision**: Layout-based protection using AuthGuard wrapper component with Navigate
**Rationale**:
- React Router v7 provides clean, declarative route protection
- Easy to preserve intended destination via `location.state.from`
- Simple loading state handling during auth check
**Alternatives Considered**:
- Higher-Order Component (HOC): More verbose in modern React
- Route-level guards: Duplicates auth logic across routes
## 5. OAuth Redirect Flow Implementation
**Decision**: Backend-initiated flow with frontend callback handler
**Flow**:
1. Frontend links to `/api/auth/google` (backend initiates OAuth)
2. NestJS redirects to Google consent screen
3. Google redirects to `/api/auth/google/callback`
4. Backend validates tokens, creates/updates user, issues JWT
5. Backend redirects to frontend `/auth/callback?token=...`
6. Frontend stores token, clears URL, redirects to intended destination
**Rationale**:
- NestJS handles OAuth state management and token exchange securely
- Supports TypeORM user creation/lookup with transaction safety
- Token cleared from URL immediately for security
**Alternatives Considered**:
- Frontend-initiated PKCE flow: More complex state management
- Popup-based flow: Poor UX on mobile, blocked by some browsers
## 6. Session Validity & Token Expiration
**Decision**:
- Access tokens: 15 minutes (short-lived for security)
- Refresh tokens: 7 days (per spec assumptions)
- Automatic token refresh via 401 interceptor in Axios
**Rationale**:
- Short access tokens limit exposure window if compromised
- 7-day refresh aligns with spec requirements
- Auto-refresh provides seamless UX
## Implementation Notes
**CORS Configuration Required**:
```
origin: FRONTEND_URL
credentials: true (allow cookies)
```
**Environment Variables Needed**:
- GOOGLE_CLIENT_ID
- GOOGLE_CLIENT_SECRET
- GOOGLE_CALLBACK_URL
- JWT_SECRET
- JWT_ACCESS_EXPIRATION (15m)
- JWT_REFRESH_EXPIRATION (7d)
- FRONTEND_URL
**TypeORM Indexes**:
- Index `googleId` for OAuth lookups
- Index `email` for user queries