- Go to Google Cloud Console
- Create a new project or select an existing one
- Navigate to APIs & Services > Credentials
- Click Create Credentials > OAuth 2.0 Client ID
- Configure the OAuth consent screen if prompted:
- User Type: External (for testing)
- Add your email as a test user
- For Application type, select Web application
- Add Authorized redirect URIs:
http://localhost:5000/api/auth/google/callback(for development)https://yourdomain.com/api/auth/google/callback(for production)
- Click Create and copy your:
- Client ID
- Client Secret
Add these to your .env file:
GOOGLE_CLIENT_ID=your_google_client_id_here
GOOGLE_CLIENT_SECRET=your_google_client_secret_here
SESSION_SECRET=your_random_session_secret_here
FRONTEND_URL=http://localhost:3000Important: Generate a strong random string for SESSION_SECRET. You can use:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"GET /api/auth/google
Redirects user to Google's OAuth consent screen.
GET /api/auth/google/callback
Google redirects here after authentication.
After successful authentication, user is redirected to:
{FRONTEND_URL}/auth/success?user={userData}
On authentication failure, user is redirected to:
{FRONTEND_URL}/login?error=google_auth_failed
const handleGoogleLogin = () => {
// Redirect to backend Google auth endpoint
window.location.href = 'http://localhost:5000/api/auth/google';
};
// In your JSX
<button onClick={handleGoogleLogin}>
Sign in with Google
</button>Create a route to handle the success redirect (e.g., /auth/success):
import { useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
function AuthSuccess() {
const [searchParams] = useSearchParams();
const navigate = useNavigate();
useEffect(() => {
const userParam = searchParams.get('user');
if (userParam) {
try {
const userData = JSON.parse(decodeURIComponent(userParam));
// Store user data in your state management (Redux, Context, etc.)
localStorage.setItem('user', JSON.stringify(userData));
// Redirect to home/dashboard
navigate('/');
} catch (error) {
console.error('Error parsing user data:', error);
navigate('/login');
}
}
}, [searchParams, navigate]);
return <div>Authenticating...</div>;
}The User model now supports:
- googleId: Google user ID
- email: User's email (from Google)
- authProvider: "local" or "google"
- password: Optional (not required for Google users)
- gender: Optional (not required for Google users)
-
Start your backend server:
npm run server
-
Navigate to:
http://localhost:5000/api/auth/google -
You should be redirected to Google's login page
-
After successful login, you'll be redirected to your frontend with user data
When deploying to production:
-
Update Google OAuth credentials:
- Add production callback URL in Google Console
- Update
FRONTEND_URLin production.env
-
Ensure
NODE_ENV=productionfor secure cookies -
Use HTTPS for both frontend and backend
- ✅ Never commit
.envfile to version control - ✅ Use strong random strings for
SESSION_SECRET - ✅ Enable HTTPS in production
- ✅ Keep Google Client Secret secure
- ✅ Regularly rotate secrets
- ✅ Add rate limiting to auth endpoints (recommended)
Issue: "Redirect URI mismatch"
- Ensure the callback URL in Google Console exactly matches your backend route
Issue: "Session not persisting"
- Check CORS configuration includes
credentials: true - Ensure frontend sends requests with
credentials: 'include'
Issue: "User not authenticated"
- Verify
SESSION_SECRETis set in.env - Check that session middleware is initialized before passport
- User clicks "Sign in with Google" on frontend
- Frontend redirects to
http://localhost:5000/api/auth/google - Backend redirects to Google's OAuth consent screen
- User authorizes the app
- Google redirects back to
http://localhost:5000/api/auth/google/callback - Backend creates/finds user, generates JWT token
- Backend redirects to frontend with user data
- Frontend stores user data and JWT cookie
- User is logged in! 🎉