✅ No tokens in frontend - Tokens never exposed to JavaScript
✅ HttpOnly cookies only - Protected from XSS attacks
✅ Server-side validation - All OAuth handled by backend
✅ CSRF protection - State parameter validation
✅ No localStorage usage - Eliminates XSS token theft risk
❌ Tokens in localStorage (XSS vulnerable) ❌ Client-side token handling ❌ Cross-origin cookie complications
1. User clicks "Sign in with Google"
↓
2. Frontend redirects to: /api/v1/user/auth/google
↓
3. Backend generates Google OAuth URL with state parameter
↓
4. Backend redirects user to Google OAuth consent screen
↓
5. User consents on Google
↓
6. Google redirects to: /api/v1/user/auth/google/callback?code=...&state=...
↓
7. Backend validates state, exchanges code for tokens
↓
8. Backend gets user info from Google
↓
9. Backend creates/updates user in database
↓
10. Backend generates JWT tokens
↓
11. Backend sets secure HttpOnly cookies
↓
12. Backend redirects to frontend: /?auth=success
↓
13. Frontend detects auth success, checks authentication status
↓
14. User is logged in! 🎉
- Go to Google Cloud Console
- Navigate to: APIs & Services → Credentials
- Edit your OAuth 2.0 Client ID
- Update Authorized redirect URIs:
http://localhost:9000/api/v1/user/auth/google/callback https://your-backend-domain.com/api/v1/user/auth/google/callback - Update Authorized JavaScript origins:
http://localhost:9000 https://your-backend-domain.com https://your-frontend-domain.com
Set these in your backend hosting service:
# Required URLs
BACKEND_URL=https://feedback-a91d.onrender.com
FRONTEND_URL=https://feedback-red-seven.vercel.app
# Google OAuth
GOOGLE_CLIENT_ID=your_client_id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your_client_secret
# Session security
SESSION_SECRET=your_super_secure_session_secret
# Other existing variables...
NODE_ENV=production
MONGODB_URI=your_mongo_connection
CORS_ORIGIN=https://feedback-red-seven.vercel.app
ACCESS_TOKEN_SECRET=your_jwt_secret
REFRESH_TOKEN_SECRET=your_refresh_secretcd Backend
npm install express-sessionReplace the old Google auth button with the new server-side version:
// In your Login/SignUp pages, replace:
import GoogleSignInButton from '../components/GoogleSignInButton';
// With:
import ServerSideGoogleAuth from '../components/ServerSideGoogleAuth';
// And use:
<ServerSideGoogleAuth text="Sign in with Google" />- Start backend:
cd Backend && npm run dev - Start frontend:
cd Frontend && npm run dev - Test OAuth: Click "Sign in with Google"
- Check logs: Monitor both backend and frontend console
- Deploy backend with new environment variables
- Deploy frontend with new component
- Update Google Console redirect URIs
- Test full OAuth flow
-
"redirect_uri_mismatch"
- Check Google Console redirect URIs match exactly
- Include both HTTP (dev) and HTTPS (prod) URLs
-
"invalid_state"
- Session not persisting between requests
- Check session middleware configuration
-
"Error 400: invalid_request"
- Check Google Client ID/Secret are correct
- Verify BACKEND_URL/FRONTEND_URL are set
-
Infinite redirect loop
- Check authentication status endpoint works
- Verify cookies are being set/read properly
Test these URLs directly:
# Backend health
GET https://your-backend.com/api/v1/health
# Auth status
GET https://your-backend.com/api/v1/user/current-user
# OAuth initiation (should redirect to Google)
GET https://your-backend.com/api/v1/user/auth/google✅ Maximum Security - No frontend token exposure
✅ Simple Implementation - Single button click
✅ Reliable Cookies - HttpOnly, secure, same-site
✅ CSRF Protection - State parameter validation
✅ Clean Architecture - Clear separation of concerns
This implementation follows OAuth 2.0 best practices and provides the highest level of security for your application! 🔒