Securing Node.js Applications with JWT and OAuth
Securing applications is a critical part of building robust and reliable Node.js projects. Two popular methods for authentication and authorization are JSON Web Tokens (JWT) and OAuth. Let’s explore how these mechanisms can secure your applications.
1. JSON Web Tokens (JWT)
JWT is a compact, self-contained token for securely transmitting information between parties as a JSON object.
A. How JWT Works
Authorization
header).B. Installing Dependencies
npm install jsonwebtoken bcryptjs
C. Implementing JWT Authentication
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const app = express();
app.use(express.json());
const SECRET_KEY = 'your_secret_key';
const users = [{ id: 1, username: 'user1', password: bcrypt.hashSync('password', 8) }];
// Login Route
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username);
if (!user || !bcrypt.compareSync(password, user.password)) {
return res.status(401).json({ message: 'Invalid credentials' });
}
const token = jwt.sign({ id: user.id, username: user.username }, SECRET_KEY, { expiresIn: '1h' });
res.json({ token });
});
// Protected Route
app.get('/protected', (req, res) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(403).json({ message: 'Token required' });
try {
const decoded = jwt.verify(token, SECRET_KEY);
res.json({ message: 'Access granted', user: decoded });
} catch {
res.status(401).json({ message: 'Invalid token' });
}
});
// Start Server
app.listen(3000, () => console.log('Server running on port 3000'));
D. Benefits of JWT
2. OAuth
OAuth is a widely-used open standard for access delegation, allowing users to grant third-party applications access to their resources without sharing credentials.
A. How OAuth Works
B. OAuth Use Case
OAuth is commonly used for "Login with Google/Facebook" functionality.
C. Setting Up OAuth with Passport.js
1. Install Dependencies:
npm install passport passport-google-oauth20
2. Implement OAuth Authentication:
const express = require('express');
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const app = express();
passport.use(new GoogleStrategy({
clientID: 'your_google_client_id',
clientSecret: 'your_google_client_secret',
callbackURL: 'http://localhost:3000/auth/google/callback',
}, (accessToken, refreshToken, profile, done) => {
// Save or verify user details here
return done(null, profile);
}));
passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((user, done) => done(null, user));
app.use(passport.initialize());
// Routes
app.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/' }),
(req, res) => res.send('Authentication successful!'));
app.listen(3000, () => console.log('Server running on port 3000'));
B. Use HTTPS
Encrypt data transmission by setting up HTTPS using an SSL certificate:
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('private-key.pem'),
cert: fs.readFileSync('certificate.pem'),
};
https.createServer(options, app).listen(443);
3. JWT vs OAuth
Feature | JWT | OAuth |
---|
Purpose | Stateless authentication | Access delegation |
Use Case | API security, user authentication | Third-party login, resource access |
Implementation | Easy | Slightly complex |
Storage | Typically stored on the client | Access tokens managed by OAuth server |