Add Google Login to ANY Express project in literally 2 minutes!
A beautiful, production-ready authentication template powered by Zoogle. Just copy, paste, and you're done! ✨
Clean, professional login with Google OAuth button
Modern signup experience with instant account creation
Protected dashboard showing user profile and info
zoogle-auth-template/
├── 📄 server.js # Complete backend (Express + Zoogle)
├── 📄 package.json # All dependencies
├── 📄 .env.example # Environment template
├── 📄 README.md # This file
└── 📁 public/
├── login.html # Beautiful login page
└── dashboard.html # Protected dashboard
npm installOr manually:
npm install express zoogle dotenv- Go to Google Cloud Console
- Create a new project (or select existing)
- Enable Google+ API (or People API)
- Navigate to Credentials → Create Credentials → OAuth 2.0 Client ID
- Add this redirect URL:
http://localhost:3000/auth/google/callback - Copy your
CLIENT_IDandCLIENT_SECRET
Create a .env file:
GOOGLE_CLIENT_ID=your_google_client_id_here
GOOGLE_CLIENT_SECRET=your_google_client_secret_here
JWT_SECRET=your_random_secret_here
PORT=3000
CALLBACK_URL=http://localhost:3000/auth/google/callbackGenerate a secure JWT_SECRET:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"npm startVisit:
- 🔐 Login: http://localhost:3000/login
- 📝 Signup: http://localhost:3000/signup
- 🏠 Dashboard: http://localhost:3000/dashboard
That's it! You're done! 🎉
┌─────────┐ ┌──────────┐ ┌────────┐ ┌──────────┐
│ User │─────▶│ Login │─────▶│ Google │─────▶│ Callback │
│ Clicks │ │ Button │ │ OAuth │ │ Handler │
└─────────┘ └──────────┘ └────────┘ └──────────┘
│
▼
┌─────────┐ ┌──────────┐ ┌────────┐ ┌──────────┐
│Dashboard│◀─────│ Store │◀─────│ Create │◀─────│ Generate │
│ Access │ │ Token │ │ User │ │ JWT │
└─────────┘ └──────────┘ └────────┘ └──────────┘
- User clicks "Continue with Google"
- Redirected to Google OAuth consent
- Google authenticates and returns to callback
- Zoogle exchanges code for user profile
findOrCreateUser()saves user to database- JWT token generated and sent to frontend
- Token stored in localStorage
- User accesses protected dashboard
Add authentication to any route:
app.get('/api/protected', googleAuth.middleware, (req, res) => {
// req.user contains authenticated user data
res.json({
message: `Welcome ${req.user.name}!`,
user: req.user
});
});// In server.js, replace findOrCreateUser:
async findOrCreateUser(profile) {
const User = require('./models/User');
return await User.findOneAndUpdate(
{ googleId: profile.id },
{
googleId: profile.id,
email: profile.email,
name: profile.name,
picture: profile.picture,
lastLogin: new Date()
},
{ upsert: true, new: true }
);
}async findOrCreateUser(profile) {
const { Pool } = require('pg');
const pool = new Pool();
const result = await pool.query(
`INSERT INTO users (google_id, email, name, picture, last_login)
VALUES ($1, $2, $3, $4, NOW())
ON CONFLICT (google_id)
DO UPDATE SET last_login = NOW()
RETURNING *`,
[profile.id, profile.email, profile.name, profile.picture]
);
return result.rows[0];
}async findOrCreateUser(profile) {
const mysql = require('mysql2/promise');
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
database: 'myapp'
});
const [rows] = await connection.execute(
`INSERT INTO users (google_id, email, name, picture, last_login)
VALUES (?, ?, ?, ?, NOW())
ON DUPLICATE KEY UPDATE last_login = NOW()`,
[profile.id, profile.email, profile.name, profile.picture]
);
return rows;
}| Method | Endpoint | Description |
|---|---|---|
| GET | /login |
Login page |
| GET | /signup |
Signup page |
| GET | /auth/google/login |
Start OAuth flow |
| GET | /auth/google/callback |
OAuth callback |
| Method | Endpoint | Description |
|---|---|---|
| GET | /dashboard |
User dashboard |
| GET | /profile |
Get user profile |
// Frontend: Call protected API
const token = localStorage.getItem('authToken');
fetch('/profile', {
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(res => res.json())
.then(data => console.log(data.user));- Ensure callback URL in Google Console matches exactly:
http://localhost:3000/auth/google/callback - Include
http://orhttps:// - Check port number
- Clear localStorage:
localStorage.clear() - Verify
JWT_SECRETis set in.env - Check token is sent in
Authorization: Bearer <token>header
- Ensure
public/folder exists with HTML files - Check
express.static('public')is configured in server.js
- Open browser console for errors
- Verify token is stored:
localStorage.getItem('authToken') - Check network tab for failed API calls
- Backend: Express.js
- Auth: Zoogle (Google OAuth 2.0)
- Frontend: HTML, Tailwind CSS, Vanilla JS
- Security: JWT tokens
- Database: Your choice (examples provided)
Perfect for:
- ✅ SaaS applications
- ✅ Admin dashboards
- ✅ Internal tools
- ✅ Customer portals
- ✅ Content management systems
- ✅ E-commerce platforms
- ✅ Social networks
- ✅ Any app needing user accounts
Contributions are welcome! Feel free to:
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing) - Open a Pull Request
MIT License - feel free to use this in any project!
- Built with Zoogle by @PersuasivePost
- Styled with Tailwind CSS
- Powered by Express.js
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 📖 Zoogle Docs: GitHub Repo
If this helped you, give it a ⭐️! It helps others discover this template.
Made with ❤️ using Zoogle
Setup Time: 2 minutes ⏱️
Code to Write: 0 lines ✨
Authentication: Enterprise-grade 🔐

