Express.js Authentication
Implement secure authentication in Express.js using JWT, sessions, Passport.js, and OAuth. Learn best practices for protecting your API.
Overview
Authentication is a critical aspect of web application security. Express.js provides flexibility in implementing various authentication strategies.
Authentication Methods
Common authentication methods include: - **Session-based**: Traditional approach using cookies and server-side sessions - **Token-based (JWT)**: Stateless authentication using JSON Web Tokens - **OAuth/OAuth2**: Third-party authentication (Google, GitHub, etc.)
JWT Authentication
JSON Web Tokens are popular for API authentication. They're stateless, scalable, and work well with modern frontend frameworks.
Passport.js
Passport is authentication middleware for Node.js. It's extremely flexible and modular, supporting many authentication strategies.
Security Best Practices
Always hash passwords, use HTTPS, implement rate limiting, and follow security best practices to protect your users.
Code Examples
JWT Authentication Setup
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
// Generate JWT token
const generateToken = (userId) => {
return jwt.sign(
{ id: userId },
process.env.JWT_SECRET,
{ expiresIn: '7d' }
);
};
// Login route
app.post('/login', async (req, res) => {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user || !await bcrypt.compare(password, user.password)) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const token = generateToken(user._id);
res.json({ token, user: { id: user._id, email: user.email } });
});Protect Routes Middleware
const protect = async (req, res, next) => {
try {
// Get token from header
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Not authorized' });
}
const token = authHeader.split(' ')[1];
// Verify token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// Attach user to request
req.user = await User.findById(decoded.id).select('-password');
if (!req.user) {
return res.status(401).json({ error: 'User not found' });
}
next();
} catch (error) {
res.status(401).json({ error: 'Not authorized' });
}
};
// Protected route
app.get('/profile', protect, (req, res) => {
res.json(req.user);
});Password Hashing
const bcrypt = require('bcryptjs');
// Hash password before saving
const hashPassword = async (password) => {
const salt = await bcrypt.genSalt(12);
return bcrypt.hash(password, salt);
};
// Register route
app.post('/register', async (req, res) => {
const { email, password, name } = req.body;
// Check if user exists
const existingUser = await User.findOne({ email });
if (existingUser) {
return res.status(400).json({ error: 'Email already registered' });
}
// Hash password
const hashedPassword = await hashPassword(password);
// Create user
const user = await User.create({
email,
password: hashedPassword,
name
});
const token = generateToken(user._id);
res.status(201).json({ token, user: { id: user._id, email } });
});Frequently Asked Questions
Should I use sessions or JWT for authentication?
How do I refresh JWT tokens?
How do I protect against brute force attacks?
Need expert help with Express.js?
Our team at Slashdev.io builds production-ready Express.js applications.