การพิสูจน์ตัวตน: Session-based vs Token-based

Authentication คือกระบวนการพิสูจน์ว่า “ผู้ใช้คือใคร” ส่วนการเลือกใช้ Session-based หรือ Token-based ต้องพิจารณาสถาปัตยกรรมของระบบ วิธี scale และประเภท client ที่ใช้งาน

Timeline/ประวัติศาสตร์

%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart LR
  subgraph Era1["ยุค Web Server / Server Session"]
    A["Session ID
Server เก็บ state"] B["Cookie
Client เก็บ session id"] end subgraph Era2["ยุค API/Mobile / Token"] C["JWT Token
Client เก็บ token"] D["Stateless API
Server ไม่เก็บ session"] end subgraph Era3["ยุค Microservices / Distributed Auth"] E["Access Token
ใช้ข้าม service"] F["Refresh Token
ต่ออายุ session"] end A --> B --> C --> D --> E --> F

แนวคิดสำคัญ

ตารางเปรียบเทียบ

หัวข้อ Session-based Token-based
State Server เก็บ session Server stateless
Client เก็บ Cookie ที่มี session id JWT หรือ token
Scale ต้องใช้ shared session store scale ง่ายกว่า
Mobile App ใช้ได้แต่ไม่คล่อง เหมาะกว่า
Revoke ลบ session ได้ทันที ต้องมี blacklist/short expiry

Mermaid Diagram: Auth Flow

%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart TD
  A["Login Request
ผู้ใช้ส่งรหัสผ่าน"] --> B{"เลือกวิธี Auth
Choose auth style"} B --> C["Session-based
Server stores session"] B --> D["Token-based
Server signs token"] C --> E["Set-Cookie
ส่ง session id"] D --> F["Access Token
ส่ง token"] E --> G["Protected Request
ตรวจ cookie"] F --> H["Protected Request
ตรวจ Authorization header"]

Code Example

// session-vs-token-demo.mjs
// ตัวอย่างแนวคิดแบบย่อ: session id และ token response
import express from 'express';
import crypto from 'node:crypto';

const app = express();
app.use(express.json());

const sessions = new Map();

app.post('/login-session', (req, res) => {
  const sessionId = crypto.randomUUID();
  sessions.set(sessionId, { userId: 1, name: 'Ana' });

  // ใน production ควรใช้ secure, httpOnly, sameSite
  res.cookie('sid', sessionId, { httpOnly: true, sameSite: 'lax' });
  res.json({ message: 'logged in with session' });
});

app.post('/login-token', (req, res) => {
  // ตัวอย่างเท่านั้น: token จริงควร sign ด้วย JWT library
  const token = Buffer.from(JSON.stringify({ sub: 1, name: 'Ana' })).toString('base64url');
  res.json({ accessToken: token });
});

app.listen(3000, () => console.log('Auth demo on http://localhost:3000'));

// ตัวอย่างการใช้งาน:
// POST /login-session เพื่อรับ cookie
// POST /login-token เพื่อรับ token

วิดีโอแนะนำ

กิจกรรมท้ายบท

กลับสัปดาห์ที่ 12