Node.js Authentication and Authorization
What is Authentication and Authorization in Node.js
Implementing user authentication and authorization in Node.js applications is crucial for securing access to resources and protecting sensitive data.
User Authentication with Passport.js:
Passport.js is a popular authentication middleware for Node.js that supports various authentication strategies, including username/password, OAuth, JWT, and more.
const express = require('express');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const session = require('express-session');
const app = express();
// Middleware for session management
app.use(session({
secret: 'secret', // Secret key used to sign the session ID cookie
resave: false,
saveUninitialized: false
}));
// Initialize Passport and session middleware
app.use(passport.initialize());
app.use(passport.session());
// Example users database
const users = [
{ id: 1, username: 'user1', password: 'password1' },
{ id: 2, username: 'user2', password: 'password2' }
];
// Passport local strategy for username/password authentication
passport.use(new LocalStrategy((username, password, done) => {
const user = users.find(u => u.username === username && u.password === password);
if (user) {
return done(null, user); // Authentication successful
} else {
return done(null, false, { message: 'Incorrect username or password' }); // Authentication failed
}
}));
// Serialize and deserialize user for session management
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
const user = users.find(u => u.id === id);
done(null, user);
});
// Route for user login
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
(req, res) => {
res.redirect('/profile');
});
// Route for accessing protected resources (requires authentication)
app.get('/profile', isAuthenticated, (req, res) => {
res.send('Welcome to your profile!');
});
// Middleware for checking authentication
function isAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
}
const port = 3000;
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
we use Passport.js to implement local authentication. When a user logs in (/login route), Passport.js verifies the username/password against the database using the LocalStrategy.
If authentication is successful, the user is redirected to the profile page (/profile).
Access to the profile page is protected by the isAuthenticated middleware, which checks if the user is authenticated before allowing access.
Managing Sessions and Tokens:
Session-Based Authentication:
we use session-based authentication, where user sessions are managed using cookies.
Passport.js serializes and deserializes user objects to and from the session store, allowing the application to maintain user sessions across requests.
Token-Based Authentication:
you can implement token-based authentication using JSON Web Tokens (JWT).
With token-based authentication, the server generates a token containing user information upon successful authentication, which the client sends with each subsequent request to access protected resources.
const jwt = require('jsonwebtoken');
// Route for user login
app.post('/login', (req, res) => {
// Authenticate user
const user = users.find(u => u.username === req.body.username && u.password === req.body.password);
if (!user) {
res.status(401).json({ message: 'Invalid username or password' });
return;
}
// Generate JWT token
const token = jwt.sign({ id: user.id, username: user.username }, 'secret', { expiresIn: '1h' });
res.json({ token });
});
// Middleware for verifying JWT token
function verifyToken(req, res, next) {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ message: 'Unauthorized' });
}
jwt.verify(token, 'secret', (err, decoded) => {
if (err) {
return res.status(401).json({ message: 'Invalid token' });
}
req.user = decoded;
next();
});
}
// Route for accessing protected resources using token-based authentication
app.get('/profile', verifyToken, (req, res) => {
res.send('Welcome to your profile!');
});