C
Network/Authentication/Lesson 06

Authentication — Cookies, Sessions, JWT & OAuth

45 min·theory

Authentication — Cookies, Sessions, JWT & OAuth

🎯 After reading this lesson

After finishing this lesson, you will be able to confidently do the following three things.

  • ✅ Differences between Cookie, Session, and JWT
  • ✅ OAuth 2.0 Authorization Code Flow + PKCE
  • ✅ Operating Access Tokens vs. Refresh Tokens

Keep these learning objectives as a checklist, and close the lesson once you can answer all of them.

Cookies + Sessions

Cookie = small pieces of data stored in the browser. Issued by the server via the Set-Cookie header.

Cookie attributes:

code
Set-Cookie: session=abc123;
  HttpOnly;          # No JS access (XSS defense)
  Secure;            # Transmit only over HTTPS
  SameSite=Lax;      # CSRF defense (blocked from external sites)
  Max-Age=86400;     # 1 day
  Path=/;
  Domain=.example.com;

SameSite options:

  • Strict — blocked from all external sites (most secure, may affect UX)
  • Lax — allows only safe methods like GET (recommended default)
  • None — allows everything (Secure flag required)

Session authentication (server-side storage):

code
1. POST /login (email+password)
2. Server: validate → generate sessionId → store in Redis
   { "sess:abc123": { userId: 42, exp: ... } }
3. Response: Set-Cookie: session=abc123 (HttpOnly)
4. Subsequent requests: browser automatically attaches
5. Server: sessionId → Redis lookup → user
6. Logout: delete from Redis → immediate invalidation

Advantages:

  • Instant invalidation
  • Small cookie (sessionId only)
  • XSS-safe with HttpOnly

Disadvantages:

  • Requires server-side storage (Redis recommended)
  • Multi-server setups need sticky sessions or shared storage
  • Tricky to handle with mobile apps and SPAs

JWT — Self-Verifying Tokens

JWT (JSON Web Token)Stateless authentication:

Structure (3 parts separated by .):

code
xxxx.yyyy.zzzz
└┬─┘ └┬─┘ └┬─┘
Header  │   Signature
     Payload

After Base64 decoding:

json
// Header
{ "alg": "HS256", "typ": "JWT" }

// Payload (claims)
{
  "sub": "42",                  // subject (user id)
  "exp": 1735689600,            // expiration
  "iat": 1735603200,            // issued at
  "role": "admin"               // custom
}

// Signature = HMAC-SHA256(header.payload, secret)

Server verification:
1. Split the token → header.payload.sig
2. Recalculate HMAC-SHA256(header.payload, secret)
3. Does it match the received sig? → Not tampered with
4. Is it before exp? → Valid
5. Trust the user info in the payload

Advantages:

  • No server storage needed (stateless)
  • Friendly for multi-server and MSA architectures
  • Clean for mobile and SPA (Authorization header)

Disadvantages:

  • Hard to invalidate — remains valid until exp (Redis blacklist needed)
  • Token size (~200–500 bytes)
  • Entire system at risk if the secret key is exposed
  • Storing in LocalStorage = XSS risk → httpOnly cookie recommended

Access + Refresh token pattern (most common):

  • Access Token: 15 minutes, used frequently
  • Refresh Token: 7 days, for renewal only (httpOnly + Secure)
  • When Access Token expires → issue a new one using the Refresh Token
  • When Refresh Token also expires → re-login required

OAuth 2.0 + OIDC

OAuth 2.0 = Delegating authentication to another site. The standard behind "Sign in with Google."Authorization Code Flow (most secure, for server apps):``1. User: Clicks "Sign in with Google"2. Our app → Google: Redirects to login page https://accounts.google.com/o/oauth2/auth? client_id=xxx&redirect_uri=https://us/cb&response_type=code&scope=email3. User logs in to Google + grants consent4. Google → Our callback: code=ABC5. Our server → Google: Exchanges code (server-to-server) POST /oauth/token { code: 'ABC', client_id, client_secret }6. Google → Our server: access_token + refresh_token7. Our server: Calls Google API with token GET /userinfo (name, email)8. Maps user in our DB + logs in`PKCE (Proof Key for Code Exchange):- Used when client_secret cannot be kept secret, such as in mobile apps and SPAs- The client generates a code_verifier- Step 1: Send code_challenge = SHA256(code_verifier)- Step 5: Send code_verifier → Google verifies it- 2025 standard — recommended even for server appsOAuth Scopes — permission boundaries:- email — email address- profile — name and profile picture- read:repos` — read GitHub repositories- Principle of least privilege (request only what you need)---OIDC (OpenID Connect) = OAuth 2.0 + authentication standard:- OAuth = authorization- OIDC = OAuth + authentication- Adds an id_token (JWT) — contains user identity information- Google, Naver, Kakao, and Apple Sign-In all use OIDCNotable libraries:- NextAuth.js (Next.js)- Spring Security OAuth2 Client- Passport.js (Express)- Auth0, Clerk, Supabase Auth (managed services)

🤖 Try asking AI like this

Once you understand the concepts in this lesson, you can give AI specific instructions — not vague requests like "fix this," but vocabulary-driven requests — and that is where token savings begin.

  • "Migrate this session authentication to JWT"
  • "Add PKCE to this OAuth 2.0 flow"

Why this reduces tokens

Without knowing the concepts, you end up asking "What does that mean?" after receiving an AI response. Those follow-up questions are what eat up tokens. Learn the concept once, and the conversation ends in a single round.

Authentication — Cookies, Sessions, JWT & OAuth - Network