express-social-auth
v1.0.0
Published
Easy-to-use social login package for Express apps with Google, Facebook, Apple, and Instagram support
Maintainers
Readme
express-social-auth
Easy-to-use social login package for Express apps with Google, Facebook, Apple, and Instagram support. Uses your app's existing database - no separate database needed!
Features
- ✅ Google, Facebook, Apple, Instagram login support
- ✅ Uses your existing database - no data duplication
- ✅ Token verification middleware for each provider
- ✅ Session-based authentication
- ✅ Easy integration with any Express app
- ✅ TypeScript ready
Installation
npm install express-social-authQuick Setup
1. Basic Setup
const express = require('express');
const mongoose = require('mongoose');
const { createSocialLogin } = require('express-social-auth');
// Connect to your database
mongoose.connect('mongodb://localhost:27017/your-app-db');
// Create social login service
const socialLogin = createSocialLogin({
database: mongoose.connection,
env: {
GOOGLE_CLIENT_ID: 'your-google-client-id',
GOOGLE_CLIENT_SECRET: 'your-google-client-secret',
FB_CLIENT_ID: 'your-facebook-client-id',
FB_CLIENT_SECRET: 'your-facebook-client-secret',
APPLE_CLIENT_ID: 'your-apple-client-id',
APPLE_TEAM_ID: 'your-apple-team-id',
APPLE_KEY_ID: 'your-apple-key-id',
APPLE_PRIVATE_KEY: 'your-apple-private-key',
INSTAGRAM_CLIENT_ID: 'your-instagram-client-id',
INSTAGRAM_CLIENT_SECRET: 'your-instagram-client-secret'
},
sessionSecret: 'your-session-secret',
corsOrigin: 'http://localhost:3000',
baseUrl: 'http://localhost:5000',
frontendUrl: 'http://localhost:3000'
});
const app = express();
// Use the social login routes
app.use('/', socialLogin.getRouter());
app.listen(5000, () => {
console.log('Server running on port 5000');
});2. Frontend Integration
// React example
const SocialLoginButtons = () => {
const backend = 'http://localhost:5000';
return (
<div>
<a href={`${backend}/auth/google`}>
<button>Login with Google</button>
</a>
<a href={`${backend}/auth/facebook`}>
<button>Login with Facebook</button>
</a>
<a href={`${backend}/auth/apple`}>
<button>Login with Apple</button>
</a>
<a href={`${backend}/auth/instagram`}>
<button>Login with Instagram</button>
</a>
</div>
);
};API Endpoints
Authentication Routes
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /auth/google | Start Google OAuth |
| GET | /auth/google/callback | Google OAuth callback |
| GET | /auth/facebook | Start Facebook OAuth |
| GET | /auth/facebook/callback | Facebook OAuth callback |
| GET | /auth/apple | Start Apple OAuth |
| POST | /auth/apple/callback | Apple OAuth callback |
| GET | /auth/instagram | Start Instagram OAuth |
| GET | /auth/instagram/callback | Instagram OAuth callback |
| GET | /auth/logout | Logout user |
| GET | /auth/user | Get current user info |
| GET | /auth/user/token | Get user with access token |
User Data Structure
{
id: "user_id",
name: "John Doe",
email: "[email protected]",
photo: "https://example.com/photo.jpg",
provider: "google", // or "facebook", "apple", "instagram"
createdAt: "2024-01-01T00:00:00.000Z",
lastLogin: "2024-01-01T00:00:00.000Z"
}Token Verification
Using Token Verifiers
const { verifyInstagramToken, verifyFacebookToken } = socialLogin.getTokenVerifiers();
// Protected route with Instagram token verification
app.get('/instagram-data', verifyInstagramToken, (req, res) => {
res.json({
message: 'Instagram token is valid!',
user: req.instagramUser
});
});
// Protected route with Facebook token verification
app.get('/facebook-data', verifyFacebookToken, (req, res) => {
res.json({
message: 'Facebook token is valid!',
user: req.facebookUser
});
});Custom Authentication Middleware
const { isAuthenticated } = socialLogin;
app.get('/protected', isAuthenticated, (req, res) => {
const user = socialLogin.getCurrentUser(req);
res.json({ message: 'Protected route', user });
});Database Integration
Using Your Existing User Model
// Get the User model from the package
const User = socialLogin.getUserModel();
// Query users
const allUsers = await User.find();
const googleUsers = await User.find({ provider: 'google' });
// Create custom user fields
const userSchema = User.schema;
userSchema.add({
customField: String,
preferences: Object
});Database Schema
The package creates a User collection with this structure:
{
provider: String, // "google", "facebook", "apple", "instagram"
providerId: String, // Unique ID from the provider
name: String, // User's display name
email: String, // User's email (if available)
photo: String, // Profile photo URL
accessToken: String, // OAuth access token
refreshToken: String, // OAuth refresh token
createdAt: Date, // Account creation date
lastLogin: Date, // Last login date
timestamps: true // Mongoose timestamps
}Environment Variables
Create a .env file in your project:
# Google OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
# Facebook OAuth
FB_CLIENT_ID=your-facebook-client-id
FB_CLIENT_SECRET=your-facebook-client-secret
# Apple OAuth
APPLE_CLIENT_ID=your-apple-client-id
APPLE_TEAM_ID=your-apple-team-id
APPLE_KEY_ID=your-apple-key-id
APPLE_PRIVATE_KEY=your-apple-private-key
# Instagram OAuth
INSTAGRAM_CLIENT_ID=your-instagram-client-id
INSTAGRAM_CLIENT_SECRET=your-instagram-client-secret
# Session
SESSION_SECRET=your-session-secret
# URLs
FRONTEND_URL=http://localhost:3000
BASE_URL=http://localhost:5000Advanced Usage
Custom Configuration
const socialLogin = createSocialLogin({
database: mongoose.connection,
env: process.env,
sessionSecret: 'super-secret-key',
corsOrigin: ['http://localhost:3000', 'https://yourdomain.com'],
baseUrl: 'https://api.yourdomain.com',
frontendUrl: 'https://yourdomain.com'
});Multiple Database Connections
// If you have multiple databases
const userDb = mongoose.createConnection('mongodb://localhost:27017/users');
const socialLogin = createSocialLogin({
database: userDb,
// ... other options
});Error Handling
// Handle authentication errors
app.use((err, req, res, next) => {
if (err.message === 'Database connection is required') {
return res.status(500).json({ error: 'Database not configured' });
}
next(err);
});Security Notes
- ✅ Access tokens are stored securely in the database
- ✅ Sensitive data is not sent to frontend by default
- ✅ Session cookies are secure in production
- ✅ CORS is properly configured
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
If you have any questions or need help, please open an issue on GitHub.
