How to implement authentication in Node.js
Implementing secure authentication in Node.js is fundamental for protecting API endpoints and managing user access in web applications and services. As the creator of CoreUI with over 25 years of backend development experience, I’ve built authentication systems for countless enterprise applications. The most effective approach is using JWT tokens with bcrypt password hashing and middleware-based route protection. This provides secure, stateless authentication that scales well and integrates seamlessly with modern frontend applications.
Use JWT tokens with bcrypt password hashing and authentication middleware to secure Node.js API endpoints and manage user sessions.
const express = require('express')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const app = express()
app.use(express.json())
// Sample users database (use real database in production)
const users = []
// Environment variables
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key'
const SALT_ROUNDS = 10
// Register endpoint
app.post('/api/auth/register', async (req, res) => {
try {
const { email, password, name } = req.body
// Validate input
if (!email || !password || !name) {
return res.status(400).json({ error: 'All fields required' })
}
// Check if user exists
const existingUser = users.find(user => user.email === email)
if (existingUser) {
return res.status(400).json({ error: 'User already exists' })
}
// Hash password
const hashedPassword = await bcrypt.hash(password, SALT_ROUNDS)
// Create user
const newUser = {
id: users.length + 1,
email,
name,
password: hashedPassword,
createdAt: new Date()
}
users.push(newUser)
// Generate JWT
const token = jwt.sign(
{ userId: newUser.id, email: newUser.email },
JWT_SECRET,
{ expiresIn: '7d' }
)
res.status(201).json({
message: 'User registered successfully',
token,
user: {
id: newUser.id,
email: newUser.email,
name: newUser.name
}
})
} catch (error) {
res.status(500).json({ error: 'Registration failed' })
}
})
// Login endpoint
app.post('/api/auth/login', async (req, res) => {
try {
const { email, password } = req.body
// Find user
const user = users.find(user => user.email === email)
if (!user) {
return res.status(401).json({ error: 'Invalid credentials' })
}
// Verify password
const isValidPassword = await bcrypt.compare(password, user.password)
if (!isValidPassword) {
return res.status(401).json({ error: 'Invalid credentials' })
}
// Generate JWT
const token = jwt.sign(
{ userId: user.id, email: user.email },
JWT_SECRET,
{ expiresIn: '7d' }
)
res.json({
message: 'Login successful',
token,
user: {
id: user.id,
email: user.email,
name: user.name
}
})
} catch (error) {
res.status(500).json({ error: 'Login failed' })
}
})
// Authentication middleware
const authenticateToken = (req, res, next) => {
const authHeader = req.headers.authorization
const token = authHeader && authHeader.split(' ')[1] // Bearer TOKEN
if (!token) {
return res.status(401).json({ error: 'Access token required' })
}
jwt.verify(token, JWT_SECRET, (err, user) => {
if (err) {
return res.status(403).json({ error: 'Invalid token' })
}
req.user = user
next()
})
}
// Protected route
app.get('/api/profile', authenticateToken, (req, res) => {
const user = users.find(user => user.id === req.user.userId)
if (!user) {
return res.status(404).json({ error: 'User not found' })
}
res.json({
id: user.id,
email: user.email,
name: user.name,
createdAt: user.createdAt
})
})
app.listen(3000, () => {
console.log('Authentication server running on port 3000')
})
This authentication system uses bcrypt for secure password hashing, JWT for stateless tokens, and middleware for protecting routes. The register endpoint creates users with hashed passwords, login verifies credentials and returns tokens, and the middleware validates tokens on protected routes.
Best Practice Note:
This authentication pattern is the foundation of CoreUI’s secure backend templates for enterprise applications. Always use environment variables for secrets, implement rate limiting on auth endpoints, and consider adding refresh tokens for enhanced security in production applications.



