Authorization and Authentication in JavaScript (Node.js)
In modern web development with Node.js, user data security and access control are critically important tasks. Authentication (verifying identity) and authorization (checking permissions) are the two pillars of any secure system. In this article, we will cover the key tools and libraries for implementing these mechanisms on the Node.js platform.
Basic Concepts
Authentication is the process of verifying that a user is who they claim to be (usually via login/password, tokens, or biometrics). Authorization is determining what actions and resources an authenticated user has access to (roles, permissions).
Popular Libraries for Node.js
1. Passport.js — Universal Authentication Strategy
Passport.js is the most popular middleware library for Express. It supports over 500 strategies: local (login/password), OAuth2 (Google, Facebook, GitHub), JWT, and many others.
const passport = require('passport');const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy( function(username, password, done) { User.findOne({ username: username }, function (err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Invalid username' }); } if (!user.validPassword(password)) { return done(null, false, { message: 'Invalid password' }); } return done(null, user); }); }));
// User serialization and deserializationpassport.serializeUser(function(user, done) { done(null, user.id);});
passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); });});2. JSON Web Tokens (JWT) — Stateless Authentication
The jsonwebtoken library allows you to create and verify JWT tokens. This is ideal for REST APIs and SPA applications.
const jwt = require('jsonwebtoken');const secretKey = process.env.JWT_SECRET;
// Creating a token on loginconst token = jwt.sign( { userId: user.id, role: user.role }, secretKey, { expiresIn: '24h' });
// Middleware for token verificationfunction authMiddleware(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
if (!token) return res.status(401).json({ error: 'Token not provided' });
jwt.verify(token, secretKey, (err, decoded) => { if (err) return res.status(403).json({ error: 'Invalid token' }); req.user = decoded; next(); });}3. bcrypt — Secure Password Hashing
Never store passwords in plain text! bcrypt is the gold standard for salted hashing.
const bcrypt = require('bcrypt');const saltRounds = 10;
// Hashing password on registrationasync function hashPassword(plainPassword) { const salt = await bcrypt.genSalt(saltRounds); const hash = await bcrypt.hash(plainPassword, salt); return hash;}
// Checking password on loginasync function checkPassword(plainPassword, hash) { return await bcrypt.compare(plainPassword, hash);}4. express-session + connect-redis — Session Management
For traditional web applications with server-side sessions, use express-session paired with Redis for scaling.
const session = require('express-session');const RedisStore = require('connect-redis')(session);
app.use(session({ store: new RedisStore({ client: redisClient }), secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production', // HTTPS httpOnly: true, maxAge: 24 * 60 * 60 * 1000 // 1 day }}))