Knowledge / Computer Science and Engineering / Authentication and authorisation: sessions, OAuth and JWT

Authentication and authorisation: sessions, OAuth and JWT

Computer Science and Engineering (B.E./B.Tech) · Web, cloud and design · free study notes for exams, placements and interviews

In short

Authentication (authN) answers "who are you?"; authorisation (authZ) answers "what are you allowed to do?". Web applications implement them with server-side sessions (state on the server, a session id in a cookie) or with tokens such as JWT (state carried in a signed token), and delegate identity to other providers using OAuth 2.0 and OpenID Connect (Login with Google, UPI/account-aggregator style consent flows). The topic appears in university papers on web technologies, information security and cryptography, in UGC-NET/GATE CS security questions, and in almost every placement interview for back-end, full-stack and cloud roles at TCS, Infosys, Wipro, Zoho, Freshworks, Razorpay, Zerodha, Paytm and product startups. It is also a compliance subject in India: the DPDP Act 2023, RBI's authentication and tokenisation directions, and CERT-In reporting rules all turn on how login and access control are built.

Explained

Authentication, authorisation and the related terms

Passwords: storage, hashing and policy

Session-based authentication (stateful)

  1. User POSTs credentials over HTTPS; server verifies the password hash.
  2. Server creates a session record (user id, roles, created-at, IP/UA) in memory, Redis or a database, keyed by a cryptographically random session id (≥128 bits of entropy).
  3. Server returns Set-Cookie: SID=...; HttpOnly; Secure; SameSite=Lax; Path=/.
  4. Browser sends the cookie automatically on every same-site request; server looks the session up and loads the user.
  5. Logout, or expiry, deletes the server-side record - instant revocation.
  6. Cookie attributes: HttpOnly (JavaScript cannot read it - blunts XSS theft), Secure (HTTPS only), SameSite=Strict/Lax/None (CSRF control; None requires Secure), Domain/Path (scope), Max-Age/Expires (persistent vs session cookie).
  7. Expiry types: *absolute* (fixed lifetime), *idle/sliding* (renewed on activity), *renewal* (rotate the id periodically).
  8. Session fixation - attacker plants a known session id before login; fix by regenerating the session id at login (and at privilege change).
  9. Session hijacking - stealing the id via XSS, network sniffing or logs; fix with HTTPS everywhere + HSTS, HttpOnly, short expiry, binding to user agent/IP (carefully - mobile IPs change).
  10. CSRF (cross-site request forgery) - because cookies are sent automatically, a third-party page can trigger a state-changing request. Fixes: synchroniser token (per-session random token in a hidden field, verified server-side), double-submit cookie, SameSite cookies, and checking Origin/Referer. CSRF tokens must *not* be HttpOnly-inaccessible to the page's own JS if the JS must send them.
  11. Scaling: sticky sessions, or shared session store (Redis/Memcached), or signed cookie-based sessions. Server-side store costs one lookup per request.

JWT and token-based authentication (stateless)

OAuth 2.0 and OpenID Connect

Authorisation design, API keys and transport security

Key points

Formulas and examples

Password entropy H = L × log₂(N) bits - L = length, N = size of the character set. Guesses to exhaust ≈ 2H; average ≈ 2H−1.
Time to brute force ≈ 2H−1 / R seconds - R = guesses per second the attacker achieves.
bcrypt work = 2c hash iterations (c = cost factor); doubling time per +1 of c.
Session id entropy ≥ 128 bits; collision risk follows the birthday bound ≈ n² / (2 × 2b) for n ids of b bits.
JWT size ≈ 1.37 × (bytes of header + payload + signature) because base64 expands data by 4/3 (plus 2 dots).
Access token lifetime T: expected worst-case misuse window after logout = T (stateless) vs ≈ 0 (server-side session).
HMAC-SHA256: tag = H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ M)) - K = secret key, M = message, ⊕ = XOR, ‖ = concatenation.

Example 1 - password entropy and cracking time. An 8-character password from lowercase + uppercase + digits: N = 26+26+10 = 62, L = 8.

Example 2 - bcrypt cost tuning. A server verifies a bcrypt hash at cost 10 in 60 ms.

Example 3 - session store vs JWT at scale. An API serves 20,000 requests/s; 80,000 users are logged in; each session record is 500 bytes.

Example 4 - JWT expiry arithmetic and skew. A token has iat = 1,756,000,000 and exp = 1,756,000,900.

Example 5 - Authorisation Code + PKCE, step by step. A React SPA at https://app.example.in logs a user in via an OIDC provider.

  1. SPA generates code_verifier (43-128 random chars) and code_challenge = base64url(SHA256(verifier)), plus random state and nonce.
  2. Redirect to /authorize?response_type=code&client_id=spa1&redirect_uri=https://app.example.in/cb&scope=openid%20profile&state=xyz&nonce=abc&code_challenge=...&code_challenge_method=S256.
  3. User authenticates and consents at the provider; browser returns to /cb?code=AX7...&state=xyz. SPA **verifies state matches**.
  4. SPA POSTs to /token with code, code_verifier, client_id (no client secret - public client). Provider recomputes SHA256(verifier) and compares with the stored challenge.
  5. Response: {access_token, id_token, refresh_token, token_type:"Bearer", expires_in:900}. SPA verifies the ID token signature via JWKS and checks iss, aud, exp, nonce.
  6. API calls carry Authorization: Bearer <access_token>; the API verifies signature, aud, exp and scopes - then checks object ownership.
// Express: session login vs JWT verify (illustrative)
app.post('/login', async (req, res) => {
  const u = await db.user(req.body.email);
  if (!u || !await bcrypt.compare(req.body.password, u.hash))
    return res.status(401).json({error: 'invalid credentials'});  // same message both cases
  req.session.regenerate(() => {            // prevents session fixation
    req.session.uid = u.id; req.session.roles = u.roles;
    res.json({ok: true});
  });
});

function auth(req, res, next) {
  const t = (req.headers.authorization || '').replace('Bearer ', '');
  try {
    req.user = jwt.verify(t, PUBLIC_KEY, {
      algorithms: ['RS256'],               // allow-list: blocks alg:none and HS/RS confusion
      issuer: 'https://id.example.in', audience: 'jobs-api', clockTolerance: 30
    });
    next();
  } catch (e) { res.status(401).json({error: 'invalid token'}); }
}
const needRole = r => (req, res, next) =>
  req.user.roles.includes(r) ? next() : res.status(403).json({error: 'forbidden'});
AspectServer-side sessionJWT (stateless)
StateOn server (Redis/DB)In the token
Lookup per requestYes (1 read)No (verify signature)
RevocationImmediate on deleteOnly at exp, or needs a denylist
Payload visibilityNothing exposedClaims readable by anyone
Horizontal scalingShared store or sticky sessionsTrivially scalable
Cross-domain / microservicesAwkwardNatural
Main riskHijacking, fixation, CSRFTheft via XSS, weak keys, no revocation
Typical size on wire~32-64 byte cookie~300-1,000 bytes per request
ArtefactIssued byAudiencePurposeTypical life
Session idApp serverApp serverLook up server-side sessionMinutes to weeks (idle timeout)
Access tokenAuthorisation serverResource server (API)Authorise API calls5-15 minutes
Refresh tokenAuthorisation serverAuthorisation serverMint new access tokensHours to months, rotated
ID token (OIDC)Identity providerClient appConvey user identityMinutes; used once at login
API keyService providerService providerIdentify a calling applicationUntil rotated

Where it is used

Interview questions

Common mistakes

Related topics

REST APIs · Back-end development with Node.js · Cloud computing basics · AWS core services · Cryptography: hashing, symmetric and public-key · Network and web security: OWASP Top 10, TLS

Open in the Knowledge reader →Find jobs →