Web Security Basics: JWT Authentication, Sessions, and CORS

MEDIUM9 min readby AdminJune 19, 2026History
0.0|0 ratingsLog in to rate

Master essential web security principles: session cookies, JSON Web Tokens (JWT), password hashing with bcrypt, and CORS headers.

#backend#security#auth#jwt#cors

Authentication: Sessions vs JWT

Authentication validates a user's identity. The two most common strategies are:

  1. Session-Based Authentication: Stateful. The server creates a session store in memory/database and sends a unique session ID cookie to the client browser. On each request, the browser submits the cookie, and the server validates it against the session store. Highly secure and easy to revoke, but hard to scale horizontally across multiple stateless servers.
  2. JWT Authentication: Stateless. Upon login, the server encrypts the user session metadata into a signed JSON Web Token (JWT) and returns it. The client stores it (e.g. in localStorage or httpOnly cookie) and attaches it as Authorization: Bearer <token> headers. The server validates the signature cryptographically without querying a database, making it extremely scalable for horizontal scaling (see Vertical vs Horizontal Scaling).

Express JWT Verification Middleware

javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const jwt = require('jsonwebtoken');

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // Bearer <token>

  if (!token) return res.sendStatus(401); // Unauthorized

  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) return res.sendStatus(403); // Forbidden (invalid token)
    req.user = user;
    next();
  });
}

Understanding CORS (Cross-Origin Resource Sharing)

CORS is a browser security mechanism that blocks client scripts from fetching resources hosted on a different domain unless specifically authorized by headers.

When a frontend on http://localhost:3000 fetches from http://localhost:5000/api, the browser sends an HTTP OPTIONS pre-flight check. The backend must respond with headers like Access-Control-Allow-Origin: http://localhost:3000 to allow the data transactions to proceed. You can configure data formats as explained in How to Pass Data to an API.

Discussion

Join the discussion! Sign in to leave comments and ask questions.

Loading discussion...