DEV Community

Gophernment
Gophernment

Posted on

OAuth เล่าแบบประวัติศาสตร์ — จากรหัสผ่าน สู่มาตรฐานโลก

OAuth เล่าแบบประวัติศาสตร์ — จากรหัสผ่าน สู่มาตรฐานโลกที่ปกป้องคนทั้งเน็ต

เคยไหม — สมัครเว็บใหม่ แล้วเจอปุ่ม "Login with Google" หรือ "Login with GitHub"

กดปุ๊บ — ไม่ต้องกรอกรหัสผ่าน — เข้าระบบปั๊บ

เบื้องหลังความมหัศจรรย์นี้คือ OAuth — มาตรฐานที่ใช้กันทั้งโลก ทุกแพลตฟอร์ม ทุกภาษา

แต่กว่าจะมาเป็น OAuth — มันมีประวัติศาสตร์ของ "วิธีพิสูจน์ตัวตน" ที่วิวัฒนาการมาหลายสิบปี

บทความนี้จะเล่าแบบไทม์ไลน์ — จากยุคแรกที่ต้องจำรหัสผ่านทุกเว็บ จนถึง OAuth 2.1 ในปัจจุบัน — และคุณจะเข้าใจว่าทำไมมันถึงปลอดภัย


บทที่ 1: ยุครหัสผ่าน — "หนึ่งเว็บ หนึ่งรหัส" (1990s)

user: "สมัครเว็บ A — ตั้งรหัสผ่าน '1234'"
user: "สมัครเว็บ B — ตั้งรหัสผ่าน '1234'"
user: "สมัครเว็บ C — ตั้งรหัสผ่าน 'abcd' (เพราะ 1234 มันซ้ำ)"

3 เดือนต่อมา...
user: "เว็บ C รหัสอะไรนะ?"
user: *กด forgot password 10 ครั้งต่อเดือน*
Enter fullscreen mode Exit fullscreen mode

ปัญหา:

  • คนใช้รหัสซ้ำ — เว็บนึงรั่ว → ทุกเว็บรั่ว
  • จำไม่ไหว — 20 เว็บ = 20 รหัส = forgot password loop
  • เว็บเห็นรหัสล้วน ๆ — เว็บเก็บรหัสเป็น plain text → hack ทีเดียวได้หมด

บทที่ 2: HTTP Basic Auth — "ใส่ใน header" (1996)

GET /admin HTTP/1.1
Authorization: Basic dXNlcjpwYXNzd29yZA==
                (base64 ของ user:password)
Enter fullscreen mode Exit fullscreen mode

"สะดวกขึ้นนิดนึง" — browser จำให้ ไม่ต้องพิมพ์ทุกครั้ง

แต่ปัญหาเดิมยังอยู่ — รหัสยังถูกส่งผ่านเน็ต (ถ้าไม่มี HTTPS = plain text) — และเว็บยังเห็นรหัส


บทที่ 3: Session Cookies — "จดจำฉัน" (ยุค 2000s)

1. User → Server: "นี่รหัสผ่านของฉัน"
2. Server → User: Set-Cookie: session=abc123
3. User → Server: Cookie: session=abc123 (ทุก request ต่อจากนี้)
Enter fullscreen mode Exit fullscreen mode

ดีขึ้นเพราะ: รหัสถูกใช้ครั้งเดียวตอน login — หลังจากนั้นใช้ session token

แต่ยังมีปัญหา:

  • Cookie ถูกขโมยได้ — XSS, CSRF, man-in-the-middle
  • Cookie ใช้ข้ามเว็บไม่ได้ — เว็บ B ไม่รู้ว่า user คนนี้ login เว็บ A แล้ว
  • ถึงจะแชร์กันได้ก็ไม่ควร — ไม่อยากให้เว็บ B เห็น session ของเว็บ A

บทที่ 4: API Keys — "นี่คือกุญแจของฉัน" (กลาง 2000s)

Authorization: ApiKey sk-abc123xyz
Enter fullscreen mode Exit fullscreen mode

"เอากุญแจไป — ใช้แทนรหัสผ่าน"

ดีขึ้นเพราะ: ไม่ต้องส่งรหัสผ่านทุกครั้ง — แต่:

  • API key มีอำนาจเต็ม — กุญแจดอกเดียวเปิดได้ทุกประตู
  • ขโมยครั้งเดียว = พังหมด — ไม่มีวันหมดอายุ
  • เว็บที่ถือ key = มีอำนาจเท่าเจ้าของ — แยกรหัสผ่านให้แต่ละเว็บไม่ได้

ถ้าให้ API key กับเว็บ A — เว็บ A มีสิทธิ์อ่านอีเมล, ส่งข้อความ, ลบบัญชี — ทุกอย่าง

ลองนึกภาพ: คุณเอารถไปจอดที่โรงแรม — คุณต้องให้กุญแจรถกับพนักงาน — แต่กุญแจดอกนั้นเปิดได้ทั้งประตูรถ และ บ้านคุณ


บทที่ 5: OAuth — "กุญแจเฉพาะทาง" (2007-2012)

OAuth เกิดขึ้นมาแก้ปัญหานี้ด้วยแนวคิดที่เรียบง่ายแต่ปฏิวัติวงการ:

"อย่าเอารหัสผ่านให้เว็บอื่น — แต่ให้ 'ตั๋ว' ที่ใช้ได้เฉพาะเรื่องที่อนุญาต"

The Valet Key Analogy

คุณขับรถหรูไปโรงแรม — พนักงานต้องเอารถไปจอด

  • API Key = ให้กุญแจรถที่เปิดได้ทุกอย่าง — บ้าน, ออฟฟิศ, ตู้เซฟ
  • OAuth Token = ให้ "กุญแจ valet" — เปิดประตูรถได้, สตาร์ทได้, ขับได้ในระยะ 100 เมตรเท่านั้น — เปิดท้ายไม่ได้, เปิดกล่องเก็บของไม่ได้

OAuth = กุญแจ valet ของโลกอินเทอร์เน็ต


บทที่ 6: OAuth ทำงานยังไง — 3 ตัวละคร

┌──────────┐      ┌──────────────┐      ┌──────────┐
│  User    │      │  Canva (App) │      │  Google  │
│ (เจ้าของ)  │      │   (ขอเข้าถึง)   │      │ (ผู้ให้สิทธิ) │
└──────────┘      └──────────────┘      └──────────┘
Enter fullscreen mode Exit fullscreen mode

ฉาก: คุณใช้ Canva อยากดึงรูปจาก Google Photos

Step 1: Canva พาคุณไป Google

Canva: "เพ่! ขอรูปหน่อย"
คุณ: "OK"
Canva: → พาคุณไป Google → "คนนี้อยากให้ฉันดูรูปเขา"
Enter fullscreen mode Exit fullscreen mode

Step 2: Google ถามคุณ

Google: "Canva จะขอ: ✅ ดูรูป ✅ ดูอัลบั้ม ❌ ลบรูป ❌ แชร์รูป
        อนุญาตไหม?"
คุณ: "✅ ดูได้อย่างเดียว"
Enter fullscreen mode Exit fullscreen mode

สังเกต: Google ไม่ถามรหัสผ่านคุณ — มันถามแค่ว่า "ให้ Canva ทำอะไรได้บ้าง"

Step 3: Google ออกตั๋วให้ Canva

Google → Canva: "นี่ Authorization Code"
Canva → Google: "ขอแลก code เป็น Access Token"
Google → Canva: "นี่ Token — ใช้ได้ 1 ชม, ดูรูปได้อย่างเดียว"
Enter fullscreen mode Exit fullscreen mode

Step 4: Canva ใช้ Token

Canva → Google Photos API: "ขอดูรูป [Token: xyz]"
Google: "Token ถูกต้อง + มีสิทธิ์ดูรูป → นี่รูป"
Enter fullscreen mode Exit fullscreen mode

จบ — Canva ไม่เคยเห็นรหัสผ่าน Google ของคุณเลย


บทที่ 7: ทำไม OAuth ถึงปลอดภัย

1. Scopes — จำกัดสิทธิ์

อ่าน email ✅
ส่ง email ❌
ลบบัญชี ❌
Enter fullscreen mode Exit fullscreen mode

Token แต่ละอันระบุว่าทำอะไรได้บ้าง — แม้ token รั่ว — คนร้ายก็ทำได้แค่ "อ่าน email" — ไม่สามารถเปลี่ยนรหัสผ่านหรือโอนเงิน

2. อายุสั้น — Access Token vs Refresh Token

Access Token:  ใช้ได้ 1 ชั่วโมง
Refresh Token: ใช้ได้ 30 วัน (ใช้ขอ Access Token ใหม่)
Enter fullscreen mode Exit fullscreen mode
  • ถ้า Access Token รั่ว — คนร้ายใช้ได้แค่ 1 ชม
  • Refresh Token เก็บไว้ที่ server เท่านั้น — ไม่ส่งไป browser

3. Authorization Code + PKCE — ป้องกัน Man-in-the-Middle

PKCE (อ่านว่า "พิก-ซี่" pixie) ย่อมาจาก Proof Key for Code Exchange

ชื่อฟังดูขลัง — แต่มันคือ "ใบเสร็จ" ที่ใช้ยืนยันว่า "คนที่มาแลก token คือคนเดียวกับที่ขอ authorization code"

ปัญหา: มือถือกับ Single Page App (React/Vue) เก็บ secret ไม่ได้ — เพราะโค้ดฝั่ง client ใครก็อ่านได้

PKCE แก้ด้วยการให้ App สร้าง "หลักฐาน" สองชิ้น:

Step 1: App สร้าง code_verifier (สุ่ม)
        → "x8g7s2..."

Step 2: App เข้ารหัส code_verifier → ได้ code_challenge
        → hash(x8g7s2...) = "D2fk..."

Step 3: App ส่ง code_challenge ไปกับคำขอ authorize
        → Google จำ code_challenge ไว้

Step 4: แลก authorization code เป็น token
        → App ต้องส่ง code_verifier กลับมาด้วย

Step 5: Google ตรวจสอบ:
        hash(code_verifier ที่ส่งมา) == code_challenge ที่จำไว้?
        ✅ ใช่ → คนเดียวกัน → ออก token
        ❌ ไม่ใช่ → คนละคน → ปฏิเสธ!
Enter fullscreen mode Exit fullscreen mode

ภาพรวม:

┌──────────┐                    ┌──────────┐
│   App    │                    │  Google  │
│ (mobile) │                    │          │
└────┬─────┘                    └────┬─────┘
     │                               │
     │ สร้าง code_verifier             │
     │ hash → code_challenge         │
     │                               │
     │──→ code_challenge ──────────→ │  จำไว้
     │                               │
     │←── authorization code ─────── │
     │                               │
     │──→ code + code_verifier ────→ │  hash(code_verifier)
     │                               │  == code_challenge ?
     │                               │  ✅ → token
     │←── access token ───────────── │
Enter fullscreen mode Exit fullscreen mode

ภาษาชาวบ้าน: คุณจองคิวด้วย "บัตรคิว" (code_challenge) — ตอนถึงคิว คุณต้องแสดง "ใบจอง" (code_verifier) ที่ตรงกับบัตรคิว — ถ้าไม่ตรง แสดงว่ามีคนอื่นแอบเอาคิวคุณไป

4. คุณยกเลิกได้ตลอด

Google Account → Security → Third-party apps → Revoke Canva
Enter fullscreen mode Exit fullscreen mode

ปุ๊บ — Token หยุดทำงานทันที — ไม่ต้องเปลี่ยนรหัสผ่าน


บทที่ 8: วิวัฒนาการ OAuth

ปี เวอร์ชัน เปลี่ยนอะไร
2007 OAuth 1.0 ใช้ cryptographic signature — ซับซ้อน ใช้ยาก
2012 OAuth 2.0 ใช้ Bearer Token — ง่ายกว่า, HTTPS บังคับ
2016 OAuth 2.0 + PKCE เพิ่ม PKCE สำหรับ mobile/SPA
2023 OAuth 2.1 รวม best practices — ตัด grant types ที่ไม่ปลอดภัยออก

OAuth 2.1 — ตัดอะไรออก

OAuth 2.0 มี 4 grant types → OAuth 2.1 เหลือ 2:
  ✅ Authorization Code + PKCE (ทุก app ต้องใช้)
  ✅ Client Credentials (server-to-server)
  ❌ Implicit Grant — ตัดทิ้ง (ไม่ปลอดภัย, token อยู่ใน URL)
  ❌ Resource Owner Password — ตัดทิ้ง (app เห็นรหัสผ่าน)
Enter fullscreen mode Exit fullscreen mode

🎯 สรุป

OAuth ไม่ได้เกิดจาก "คิดดีไซน์สวย ๆ แล้วออกมาเลย" — มันเกิดจากวิวัฒนาการของปัญหา:

Password per site → Basic Auth → Session → API Key → OAuth
   (จดไม่ไหว)     (plain text)  (ข้ามเว็บไม่ได้) (อำนาจเต็ม)
Enter fullscreen mode Exit fullscreen mode

แนวคิดหลักของ OAuth:

อย่าให้รหัสผ่านกับใคร — ให้ "ตั๋ว" ที่จำกัดสิทธิ์ + จำกัดเวลา — และคุณยกเลิกได้ทุกเมื่อ


📚 อ่านต่อ:

Top comments (0)