跪拜 Guibai
← Back to the summary

Session-Cookie, JWT, and SSO: How Web Authentication Actually Works

Web Authentication Scheme Technical Guide

This document introduces common authentication schemes in web applications, including Session-Cookie, JWT, and SSO single sign-on, helping developers understand the principles, differences, and applicable scenarios of each scheme.

1. Authentication Scheme Overview

The core problem of web authentication is: HTTP is a stateless protocol, how does the server identify the user?

graph LR
    A[User] -->|Request| B[Server]
    B -->|Who are you| A

    subgraph Solution
        C[Session Cookie]
        D[JWT Token]
        E[OAuth SSO]
    end

Authentication vs Authorization

Concept English Problem Solved Analogy
Authentication Authentication Who are you? ID card
Authorization Authorization What can you do? Access card

2. Session-Cookie Scheme

2.1 Working Principle

Session-Cookie is a traditional stateful authentication scheme where user login information is stored on the server side.

sequenceDiagram
    participant U as User
    participant C as Client
    participant S as Server
    participant R as Redis/Memory

    U->>C: Enter username and password
    C->>S: POST /login
    S->>S: Verify credentials
    S->>R: Create Session<br/>store user info
    R-->>S: sessionId
    S-->>C: Set-Cookie: sessionId=abc123

    Note over C: Cookie stored automatically

    U->>C: Request data
    C->>S: GET /api/data<br/>Cookie: sessionId=abc123
    S->>R: Query Session
    R-->>S: User info
    S-->>C: Return data

2.2 Code Example

// Server - Express + express-session
import session from 'express-session';
import RedisStore from 'connect-redis';

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: 'your-secret-key',
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,      // HTTPS only
    httpOnly: true,    // Prevent XSS reading
    maxAge: 24 * 60 * 60 * 1000  // 24 hours
  }
}));

// Login
app.post('/login', async (req, res) => {
  const { username, password } = req.body;
  const user = await validateUser(username, password);

  if (user) {
    req.session.userId = user.id;
    req.session.role = user.role;
    res.json({ success: true });
  }
});

// Auth middleware
const authMiddleware = (req, res, next) => {
  if (req.session.userId) {
    next();
  } else {
    res.status(401).json({ error: 'Unauthorized' });
  }
};

2.3 Pros and Cons

Pros Cons
Server has full control, can kick users anytime Requires Session storage (Redis/Memory)
Session ID is small Distributed systems need shared Session
High security (HttpOnly) CSRF attack risk
Simple and mature implementation Complex cross-domain handling
- Limited Cookie support on mobile

3. JWT Scheme

3.1 What is JWT

JWT (JSON Web Token) is a stateless authentication scheme where user information is encoded in the Token and stored on the client side.

JWT Structure: Header.Payload.Signature

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.    <- Header (Base64)
eyJ1c2VySWQiOjEyMywiZXhwIjoxNjk5OTk5fQ.  <- Payload (Base64)
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw <- Signature
flowchart LR
    subgraph Header
        A[alg HS256<br/>typ JWT]
    end

    subgraph Payload
        B[userId 123<br/>exp 1699999]
    end

    subgraph Signature
        C[HMACSHA256]
    end

    A --> D[Base64]
    B --> D
    C --> D
    D --> E[JWT Token]

3.2 Working Principle

sequenceDiagram
    participant U as User
    participant C as Client
    participant S as Server

    U->>C: Enter username and password
    C->>S: POST /login
    S->>S: Verify credentials
    S->>S: Generate JWT<br/>(contains user info + signature)
    S-->>C: Return token

    Note over C: Store in localStorage

    U->>C: Request data
    C->>C: Read token from localStorage
    C->>S: GET /api/data<br/>Authorization: Bearer xxx
    S->>S: Verify signature<br/>parse user info<br/>(no DB lookup needed)
    S-->>C: Return data

3.3 Token Transmission Methods

Method Security Applicable Scenario
Authorization Header High Recommended, API requests
HttpOnly Cookie High Same-domain web applications
URL Query Parameter Low Only for special cases like download links, email verification
// Method 1: Authorization Header (Recommended)
axios.get('/api/data', {
  headers: {
    'Authorization': `Bearer ${token}`
  }
});

// Method 2: Auto-add via interceptor
axios.interceptors.request.use((config) => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers['Authorization'] = `Bearer ${token}`;
  }
  return config;
});

3.4 Token Refresh Mechanism

Since JWT cannot be actively invalidated, a dual Token mechanism is usually adopted:

sequenceDiagram
    participant C as Client
    participant S as Server

    Note over C,S: Obtain dual Tokens at login
    C->>S: POST /login
    S-->>C: accessToken (15 minutes)<br/>refreshToken (7 days)

    Note over C,S: Access Token expired
    C->>S: GET /api/data (accessToken expired)
    S-->>C: 401 Unauthorized

    Note over C,S: Use Refresh Token to refresh
    C->>S: POST /refresh (refreshToken)
    S->>S: Verify refreshToken
    S-->>C: New accessToken

    C->>S: GET /api/data (new accessToken)
    S-->>C: Return data
// Dual Token refresh implementation
interface TokenPair {
  accessToken: string;   // Short-term, 15 minutes
  refreshToken: string;  // Long-term, 7 days
}

// Response interceptor - auto refresh
axios.interceptors.response.use(
  response => response,
  async error => {
    if (error.response?.status === 401) {
      const refreshToken = localStorage.getItem('refreshToken');

      try {
        const { data } = await axios.post('/auth/refresh', { refreshToken });
        localStorage.setItem('accessToken', data.accessToken);

        // Retry original request
        error.config.headers['Authorization'] = `Bearer ${data.accessToken}`;
        return axios(error.config);
      } catch {
        // Refresh Token also expired, redirect to login
        window.location.href = '/login';
      }
    }
    return Promise.reject(error);
  }
);

3.5 Pros and Cons

Pros Cons
Stateless, naturally supports distributed systems Cannot be actively invalidated (needs blacklist)
Self-contained user info, reduces DB lookups Token is large (200+ bytes)
Cross-domain friendly Renewal mechanism is complex
Cross-platform (Web/App/Mini Program) Sensitive info cannot be placed in Payload
Microservice architecture friendly XSS can steal (if stored in localStorage)

4. Session vs JWT Comparison

4.1 Architecture Comparison

flowchart TB
    subgraph Session Scheme
        A1[Client] -->|Session ID| B1[Server]
        B1 -->|Query| C1[(Session Storage<br/>Redis/Memory)]
    end

    subgraph JWT Scheme
        A2[Client] -->|JWT Token<br/>contains user info| B2[Server]
        B2 -->|Only verify signature| B2
    end

4.2 Detailed Comparison

Feature Session-Cookie JWT
State Storage Server-side (Redis/Memory) Client-side (Token self-contained)
Scalability Needs shared Session storage Naturally supports distributed
Server Load Queries Session on every request Only verifies signature, no IO
Logout/Kick Delete Session directly Difficult (needs blacklist mechanism)
Security Risk CSRF attack XSS attack
Cross-domain Needs Cookie configuration Naturally supported
Mobile Cookie handling is troublesome Friendly
Token Size ~6 bytes (Session ID) ~200+ bytes
Implementation Complexity Simple Medium (needs refresh handling)

4.3 Distributed Scenario Comparison

graph TB
    subgraph Session Distributed Problem
        U1[User] --> LB1[Load Balancer]

        LB1 --> S1[Server A<br/>Has Session]
        LB1 --> S2[Server B<br/>No Session]

        S1 -.-> R1[(Shared Redis)]
        S2 -.-> R1
    end
graph TB
    subgraph JWT No Such Problem
        U2[User<br/>carries Token] --> LB2[Load Balancer]

        LB2 --> S3[Server A]
        LB2 --> S4[Server B]

        S3 --> V1[Verify Token Locally]
        S4 --> V2[Verify Token Locally]

        V1 --> N1[No Shared Storage Needed]
        V2 --> N1
    end

5. SSO Single Sign-On

5.1 What is SSO

SSO (Single Sign-On): Log in once, access everywhere.

flowchart LR
    subgraph Without SSO
        U1[User] -->|Login| A1[System A]
        U1 -->|Login again| B1[System B]
        U1 -->|Login again| C1[System C]
    end
graph TB
    subgraph SSO Single Sign-On
        U2[User] -->|Login once| SSO[SSO Auth Center]

        SSO -->|Auto pass| A2[System A]
        SSO -->|Auto pass| B2[System B]
        SSO -->|Auto pass| C2[System C]
    end

5.2 Common Scenarios

Scenario Description
Google Suite Log into Gmail, YouTube and Drive auto-login
Alibaba Suite Log into Taobao, Tmall and Alipay auto-login
Enterprise Intranet Log into OA, email, CRM, ERP all accessible
WeChat Ecosystem Log into WeChat, mini-programs share login state

5.3 SSO Implementation Schemes

Scheme 1: Shared Cookie (Same Domain)

Suitable for subsystems under the same main domain.

flowchart TB
    subgraph example.com Subdomains
        SSO[sso.example.com<br/>Auth Center]
        A[a.example.com<br/>System A]
        B[b.example.com<br/>System B]
        C[c.example.com<br/>System C]
    end

    Cookie[Cookie set to .example.com<br/>shared by all subdomains]

    SSO --> Cookie
    A --> Cookie
    B --> Cookie
    C --> Cookie
// Set shared Cookie
res.cookie('token', jwtToken, {
  domain: '.example.com',  // Main domain, shared by all subdomains
  httpOnly: true,
  secure: true
});

Scheme 2: CAS Protocol (Cross-domain)

Suitable for systems with different domain names.

sequenceDiagram
    participant U as User
    participant A as System A<br/>(app-a.com)
    participant SSO as SSO Center<br/>(sso.com)

    Note over U,SSO: First visit to System A
    U->>A: 1. Visit System A
    A->>A: 2. Detect not logged in
    A-->>U: 3. Redirect to SSO
    U->>SSO: 4. Jump to SSO login page
    U->>SSO: 5. Enter username and password
    SSO->>SSO: 6. Verification successful<br/>create global Session
    SSO-->>U: 7. Redirect back to System A<br/>carrying ticket
    U->>A: 8. Visit with ticket
    A->>SSO: 9. Verify ticket
    SSO-->>A: 10. Return user info
    A->>A: 11. Create local Session
    A-->>U: 12. Login successful
sequenceDiagram
    participant U as User
    participant B as System B<br/>(app-b.com)
    participant SSO as SSO Center<br/>(sso.com)

    Note over U,SSO: Visit System B (already logged into SSO)
    U->>B: 1. Visit System B
    B->>B: 2. Detect not logged in
    B-->>U: 3. Redirect to SSO
    U->>SSO: 4. Jump to SSO
    SSO->>SSO: 5. Detect existing global Session
    SSO-->>U: 6. Directly return ticket<br/>(no need to log in again)
    U->>B: 7. Visit with ticket
    B->>SSO: 8. Verify ticket
    SSO-->>B: 9. Return user info
    B-->>U: 10. Auto login successful

Scheme 3: OAuth 2.0 / OIDC

Modern standard, suitable for third-party login and open platforms.

sequenceDiagram
    participant U as User
    participant App as Third-party App
    participant Auth as Auth Server<br/>(e.g., GitHub)
    participant API as Resource Server

    U->>App: 1. Click "GitHub Login"
    App-->>U: 2. Redirect to GitHub
    U->>Auth: 3. Jump to GitHub auth page
    U->>Auth: 4. User authorizes
    Auth-->>U: 5. Redirect back to App<br/>carrying code
    U->>App: 6. Visit with code
    App->>Auth: 7. Exchange code for token
    Auth-->>App: 8. Return access_token
    App->>API: 9. Use token to get user info
    API-->>App: 10. Return user data
    App-->>U: 11. Login successful

5.4 SSO Protocol Comparison

Protocol Features Applicable Scenario
Shared Cookie Simple and direct Same-domain systems
CAS Classic enterprise solution Internal enterprise systems
OAuth 2.0 Authorization protocol Third-party login, open APIs
OIDC OAuth 2.0 + Identity layer Modern standard solution
SAML XML format, enterprise-grade Traditional enterprises, government

5.5 Relationship between SSO and JWT/Session

flowchart TB
    subgraph SSO Architecture Scheme
        SSO[SSO Single Sign-On]
    end

    subgraph Underlying Implementation
        JWT[JWT Token]
        Session[Session Cookie]
    end

    SSO --> JWT
    SSO --> Session

    SSO --> Note[Solves multi-system shared login]
    JWT --> Note2[Solves single-system user identification]
    Session --> Note2

6. Scheme Selection Guide

6.1 Decision Flowchart

flowchart TB
    Start[Start Selection] --> Q1{Multiple Systems?}

    Q1 -->|Yes| Q2{Same Domain?}
    Q1 -->|No| Q3{Distributed?}

    Q2 -->|Yes| A1[Shared Cookie SSO]
    Q2 -->|No| A2[CAS/OAuth SSO]

    Q3 -->|Yes| Q4{Need Instant Kick?}
    Q3 -->|No| A3[Session-Cookie]

    Q4 -->|Yes| A4[JWT + Blacklist]
    Q4 -->|No| A5[Pure JWT]

6.2 Scenario Recommendations

Scenario Recommended Scheme Reason
Monolithic Application Session-Cookie Simple, reliable, supports instant kick
Microservice Architecture JWT Stateless, independent service verification
Mobile App JWT No Cookie limitations
Enterprise Multi-system SSO (CAS) Unified authentication management
Third-party Login OAuth 2.0 / OIDC Industry standard
Open API Platform OAuth 2.0 + JWT Flexible authorization, Token self-contained
High Security Requirements Session + Short-term Token Strong controllability

6.3 Security Recommendations

flowchart LR
    subgraph Defense Measures
        A[HTTPS Transmission]
        B[HttpOnly Cookie]
        C[SameSite Cookie]
        D[CSRF Token]
        E[XSS Protection]
        F[Token Expiration Mechanism]
    end

    A --> Safe[Secure Authentication]
    B --> Safe
    C --> Safe
    D --> Safe
    E --> Safe
    F --> Safe
Attack Type Session Scheme JWT Scheme
XSS HttpOnly protection Avoid localStorage, or use HttpOnly Cookie
CSRF Needs CSRF Token Using Header to pass Token provides natural protection
Replay Attack Session expiration mechanism Token expiration + Refresh Token
Man-in-the-Middle HTTPS HTTPS

References

Comments

Top 1 from juejin.cn, machine-translated. The original thread is authoritative.

亚雷

The authentication comparison is very clear!