SynfraCore
Synfracore
Start Learning
Navigation

Academies

Platform

RoadmapsLabsCertificationsInterviewPYQsAI AssistantCareer
Start Learning Free Learning Roadmaps

Authentication & Authorization β€” Overview

What it is, why it matters, architecture and key concepts

πŸ“„
Last updated Sep 2026
Expert Content

Authentication & Authorization

Prove who you are, then decide what you're allowed to do

Category: Backend / Web Development

Learning Path: What β†’ Why β†’ Learning Modules β†’ Production Example β†’ Interview Prep

Before you start: you need basic Express comfort β€” defining routes, understanding the middleware pipeline ((req, res, next)), and reading a request's headers/body. This page does not re-teach Express itself β€” that's covered in this platform's own Express.js technology. See the Prerequisites tab for the full detail.


What is Authentication & Authorization?

These are two different questions, constantly confused as if they were one, and conflating them is a genuinely common real mistake with real consequences. Think of walking into a large office building: authentication is showing your ID at the front desk β€” proving you actually are who you claim to be. Authorization is what your keycard opens once you're inside β€” which floors, which rooms, which doors. Passing the front desk (authentication) tells the building nothing about which floors you should reach; a valid ID doesn't imply access to the server room. Those are two separate, sequential decisions, and a system that only checks one of them is broken, no matter how well it implements the other.

Technically: authentication verifies identity β€” a username/password pair checked against a stored (hashed) credential, a token proving a prior successful login, a biometric check. Authorization decides what that now-identified user is permitted to do β€” read this resource, delete that record, access an admin panel. A system can authenticate perfectly and still be catastrophically insecure if its authorization checks are missing or wrong (a logged-in regular user who can hit an admin-only API route just because they're logged in at all, not because they were ever granted that role).

The reason either of these needs solving at all is that HTTP is stateless β€” each request arrives with no memory of any previous one. Without a mechanism to carry "who this is" forward, a server would need the user to re-prove their identity on every single request. Sessions and tokens are the two dominant mechanisms for solving that β€” different tradeoffs, covered in Module 01, but both exist to answer the same underlying problem: making a stateless protocol behave as if it remembers you.

Login Request
Username + password submitted
Credential Verification
Compare against stored hash
Session/Token Issued
Proof of identity handed to client
Subsequent Request
Client sends proof (cookie/header)
Authorization Check
Is THIS identity allowed to do THIS?

Why Authentication & Authorization?

Almost every real application beyond a static brochure site needs to answer two questions on nearly every request: who is this, and what can they do. Without authentication, there's no way to show a user their own data instead of someone else's, no way to know who performed an action, no way to personalize anything. Without authorization, an authenticated identity is meaningless as a security boundary β€” any logged-in user could act as any other, or as an admin, purely by knowing a URL.

This is also one of the highest real-stakes topics in this academy. A bug in, say, a date-formatting utility produces a wrong-looking date. A bug in authentication or authorization produces an actual account takeover, an actual data breach, an actual regulatory incident β€” the failure mode is a real compromise, not a cosmetic defect. Getting the underlying mechanics right β€” how passwords are stored, how a token proves what it claims to prove, why "logged in" and "allowed to do X" are separate checks β€” is not optional rigor for this topic; it's the entire point.


Learning Modules

Module 01 β€” Sessions vs Tokens β€” the Core Tradeoff

Two different ways to make a stateless protocol remember who you are

A session keeps identity state on the server β€” a session store (in memory, Redis, a database) holds "session ID X belongs to user 42," and the client only carries a small, opaque session ID (usually in a cookie). A token (typically a JWT) keeps identity state on the client itself β€” the token is the proof, self-contained and cryptographically signed, and the server verifies it without needing to look anything up in a store, at least for basic validity.

Session-Based
Server holds state (session store). Client holds only an opaque ID. Easy to revoke instantly β€” delete the server-side record.
Token-Based (JWT)
Client holds self-contained, signed proof. Server verifies without a lookup. Hard to revoke before expiry β€” the token stays valid until it expires.

Topics covered:

β€’Why HTTP is stateless and what that actually means β€” 🟒 Beginner
β€’Cookies as the transport mechanism for session IDs β€” 🟒 Beginner
β€’Server-side session stores (memory, Redis) β€” 🟑 Intermediate
β€’Stateless vs stateful tradeoffs, revocation implications β€” 🟑 Intermediate

Module 02 β€” Implementing JWT-Based Auth

Structure, signing, and building it in Express

Topics covered:

β€’Password hashing with bcrypt/argon2 β€” 🟒 Beginner
β€’JWT structure: header.payload.signature β€” 🟒 Beginner
β€’Signing and verifying tokens in Express middleware β€” 🟑 Intermediate
β€’"Signed, not encrypted" β€” what that actually means for the payload β€” 🟑 Intermediate
β€’Refresh token rotation β€” πŸ”΄ Advanced

Module 03 β€” OAuth & Third-Party Sign-In

Letting users sign in with an existing identity instead of a new password

Topics covered:

β€’The authorization code flow, conceptually β€” 🟑 Intermediate
β€’OAuth vs OpenID Connect β€” authorization vs identity β€” 🟑 Intermediate
β€’Why the implicit flow is now discouraged β€” πŸ”΄ Advanced
β€’Multi-factor authentication as a second, independent factor β€” πŸ”΄ Advanced

Production Example

bash
# Production Runbook -- "users are getting logged out randomly, support tickets rising"

# Step 1: Reproduce and categorize -- is it EVERY user, or a subset?
# Check whether it correlates with a deploy, a specific route, or time-of-day
grep "401" /var/log/app/access.log | tail -100
# A spike immediately after a deploy points at a config/secret mismatch,
# not gradual token expiry

# Step 2: Distinguish session-store failure from token expiry -- they look
# identical to the user ("logged out") but have completely different fixes
redis-cli -h $SESSION_STORE_HOST PING
redis-cli -h $SESSION_STORE_HOST KEYS "sess:*" | wc -l
# If the session store was restarted/flushed (a Redis eviction policy, an
# out-of-memory event, a deploy that recreated the store), every session
# disappears at once -- this is a session-store problem, not a token one

# Step 3: If using JWTs, check whether the signing secret differs between
# the instance that issued the token and the instance verifying it --
# a rolling deploy with an env var that changed mid-rollout is a classic cause
echo $JWT_SECRET | sha256sum   # compare across all running instances
# jwt.verify() fails immediately if the secret doesn't match -- this
# LOOKS like "logged out" from the user's perspective but is actually a
# signature verification failure, not expiry

# Step 4: Check actual token/session lifetime configuration against what's
# assumed -- a short-lived access token with no working refresh flow presents
# identically to a real bug even though the token is "working as configured"
grep -r "expiresIn" src/auth/

# Step 5: Fix and verify -- confirm the secret is identical across every
# instance (a shared secrets manager, not per-instance env files), confirm
# the session store's persistence/eviction policy matches expectations, and
# confirm refresh-token flow actually renews access tokens before expiry

Interview Prep

PSR Formula: Answer every question: Problem β†’ Solution β†’ Result. 45-90 seconds max.

Common Interview Questions

Q1. What's the difference between authentication and authorization?

A: Problem: these two terms get used interchangeably in casual conversation, but they're genuinely different security decisions. Solution: authentication verifies who someone is (credential/token check); authorization decides what that verified identity is allowed to do (role/permission check) β€” like showing ID at a front desk versus what a keycard actually opens once inside. Result: a system needs both, checked separately and in that order β€” authenticating correctly says nothing about what the user should be permitted to do next.


Q2. Why must passwords be hashed rather than encrypted or stored in plaintext?

A: Problem: plaintext storage means a single database breach exposes every user's actual password directly, and encryption is reversible β€” anyone with the decryption key (including an attacker who compromises the server) can recover the original passwords too. Solution: a hash (via bcrypt or argon2) is a one-way function β€” there's no key that turns a hash back into the password, only slow, computationally expensive brute-forcing per guess, deliberately, since these algorithms are designed to be slow. Result: even a full database breach doesn't hand an attacker usable passwords directly, and since many users reuse passwords across sites, this containment matters far beyond just this one application.


Q3. What's the tradeoff between session-based and token-based (JWT) authentication?

A: Problem: teams often pick JWTs by default without weighing the actual tradeoff. Solution: sessions keep state server-side β€” trivially revocable (delete the record) but require a shared store and a lookup on every request; JWTs are self-contained and stateless β€” no server lookup needed, but hard to revoke before they naturally expire, since the token itself is the proof. Result: sessions suit apps that need instant, reliable revocation (banking, admin panels); stateless JWTs suit distributed APIs where avoiding a shared session store simplifies horizontal scaling β€” the "right" choice depends on which cost the application can actually tolerate.


Q4. Are JWTs encrypted? What does "signed, not encrypted" actually mean?

A: Problem: this is a genuinely common and dangerous misconception β€” assuming a JWT's payload is hidden from anyone who intercepts it. Solution: a standard JWT's payload is base64-encoded, not encrypted β€” anyone can decode and read it (paste one into jwt.io to see this directly). The signature only proves the token wasn't tampered with since it was issued; it does not hide the contents. Result: never put secret data (passwords, sensitive PII) directly in a JWT payload β€” treat it as visible, tamper-evident, not confidential.


Q5. httpOnly cookies vs localStorage for storing a token β€” which is safer, and why?

A: Problem: localStorage is directly readable by any JavaScript running on the page β€” including malicious JavaScript injected via an unrelated XSS vulnerability elsewhere in the app. Solution: an httpOnly cookie is inaccessible to JavaScript entirely β€” the browser attaches it automatically, but document.cookie can't read it, so an XSS payload can't exfiltrate it directly. Result: httpOnly cookies are the stronger default for storing auth tokens against XSS specifically β€” the real tradeoff then shifts to defending against CSRF, which cookie-based auth is newly exposed to and localStorage-based auth isn't.


Q6. What is CSRF, and why does it matter even with cookies marked Secure?

A: Problem: Secure on a cookie only means "only sent over HTTPS" β€” it says nothing about which site triggered the request that carries it. Solution: Cross-Site Request Forgery exploits the browser's automatic behavior of attaching cookies to any request to a domain, even one triggered by a malicious page the user merely has open in another tab β€” the request looks legitimate to the server because the valid session cookie rides along regardless of origin. Result: CSRF tokens (a value the attacker's page can't know or forge) and SameSite cookie attributes are the actual defenses β€” "Secure" alone defends transport, not request origin, and conflating the two leaves a real gap.


Q7. Explain the OAuth 2.0 authorization code flow at a conceptual level.

A: Problem: letting a third-party app authenticate a user without ever handing that app the user's actual password to the identity provider. Solution: the user is redirected to the identity provider (Google, GitHub) to authenticate directly with it; on success, the provider redirects back with a short-lived authorization code (not a token yet); the app's own backend then exchanges that code β€” server-to-server, using a client secret β€” for an actual access token. Result: the access token never touches the browser or any client-side JavaScript during the exchange itself, which is exactly why this flow is the production-correct one, over the now-discouraged implicit flow that returned tokens directly in the browser redirect.


Q8. OAuth vs OpenID Connect β€” what's the actual difference?

A: Problem: these names get used interchangeably, but they solve different problems. Solution: OAuth 2.0 is fundamentally an authorization protocol β€” it grants an app permission to access a resource on a user's behalf (e.g. read their calendar), without necessarily proving who the user is in a standardized way. OpenID Connect (OIDC) is a thin identity layer built on top of OAuth 2.0 that adds a standardized ID token specifically for authentication β€” proving who the user is. Result: "Sign in with Google" is really OIDC (identity) riding on OAuth's mechanics (authorization) β€” using bare OAuth alone for login, without OIDC's ID token, was a common and real source of security bugs in early "social login" implementations.


Q9. Why is revoking a JWT before its natural expiry a genuinely hard problem?

A: Problem: a JWT is self-contained and stateless by design β€” the server verifies it using only the signature and the token's own claims, with no database lookup. Solution: there's no built-in mechanism to "un-issue" one early; workarounds all reintroduce some server-side state β€” a blocklist of revoked token IDs (checked on every request, which partially defeats statelessness), very short-lived access tokens paired with a separately revocable refresh token, or a version/timestamp claim checked against a per-user "valid since" value in the database. Result: this is why short access-token lifetimes plus a revocable refresh token is the standard production pattern β€” it bounds the damage window of an unrevocable stolen token rather than solving revocation directly.


Q10. What does multi-factor authentication actually add, security-wise?

A: Problem: a password alone is "something you know" β€” and something you know can be phished, reused across a breached site, or guessed. Solution: MFA requires a second, independent factor β€” typically "something you have" (a time-based code from an authenticator app, a hardware key) β€” so a compromised password alone is no longer sufficient to authenticate. Result: this is why MFA meaningfully raises the bar even against a fully leaked password database β€” the attacker still needs to separately compromise a different category of proof, not just the same one twice.


Official Resources

β€’[OWASP Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html)
β€’[jwt.io](https://jwt.io/) β€” decode and inspect JWTs directly
β€’[OAuth 2.0 (oauth.net)](https://oauth.net/2/)

Try It (2 Minutes)

Paste this into a Node REPL (npm install jsonwebtoken first) and inspect what a JWT actually contains:

javascript
const jwt = require('jsonwebtoken');

const token = jwt.sign({ userId: 42, role: 'user' }, 'a-secret-key', { expiresIn: '1h' });
console.log(token); // three base64 segments, separated by dots

// Decode WITHOUT verifying -- anyone can do this, no secret needed
console.log(jwt.decode(token));
// { userId: 42, role: 'user', iat: ..., exp: ... }  <- fully readable

Notice the payload is readable without the secret at all β€” that's the "signed, not encrypted" distinction from Q4 above, made concrete. Now try jwt.verify(token, 'wrong-secret') and watch it throw β€” that's what the signature actually protects.

Share:
Join our Community
Daily tips, job alerts, interview help β€” join engineers learning together
β†’
Up Next
βœ…
Authentication & Authorization β€” Prerequisites
What to know or set up before starting
Also Worth Exploring
← Back to all Authentication & Authorization modules
Prerequisites β†’