• jwt
  • auth
  • authentication
  • identity
  • api
  • openid
  • oauth

JSON Web Token (JWT) คืออะไร?

ทำความเข้าใจพื้นฐานของ JSON Web Token (JWT) อย่างชัดเจนในเวลา 5 นาที

Gao
Gao
Founder

JSON Web Token (JWT) ได้รับการใช้งานอย่างแพร่หลายในแอปพลิเคชันเว็บสมัยใหม่และมาตรฐานเปิด เช่น OpenID Connect ช่วยในการรับรองตัวตนและการอนุญาต แม้ว่า RFC 7519 อย่างเป็นทางการจะเป็นเอกสารอ้างอิงที่สำคัญ แต่ก็อาจเป็นเรื่องยากที่จะเข้าใจสำหรับผู้เริ่มต้น ในบทความนี้ เราจะมุ่งเน้นไปที่แนวคิดพื้นฐานของ JWT และนำเสนอด้วยภาษาที่เข้าใจง่ายพร้อมตัวอย่าง

ทำไมเราจึงต้องการ JWT?

ในปัจจุบัน การใช้ JSON ในการแลกเปลี่ยนข้อมูลระหว่างสองฝ่ายเป็นเรื่องปกติ ลองพิจารณาวัตถุ JSON ที่แสดงผู้ใช้ดังนี้:

sub ย่อมาจาก "subject" ซึ่งเป็น ข้อมูลอ้างอิงมาตรฐาน ใน OpenID Connect เพื่อแสดงตัวระบุผู้ใช้ (user ID)

เราจะรับประกัน ความสมบูรณ์ ของวัตถุ JSON นี้ได้อย่างไร? พูดอีกนัยหนึ่ง เราจะมั่นใจได้อย่างไรว่าข้อมูลไม่ได้ถูกดัดแปลงระหว่างการส่ง วิธีการแก้ไขที่พบบ่อยคือการใช้ลายเซ็นดิจิทัล ตัวอย่างเช่น เราสามารถใช้ การเข้ารหัสคีย์สาธารณะ: เซิร์ฟเวอร์ลงนามวัตถุ JSON ด้วยกุญแจส่วนตัว และไคลเอนต์สามารถตรวจสอบลายเซ็นได้ด้วยกุญแจสาธารณะของเซิร์ฟเวอร์

ในสรุป JWT นำเสนอวิธีการมาตรฐานในการเป็นตัวแทนของวัตถุ JSON และลายเซ็นของมัน

รูปแบบของ JWT

เนื่องจากมีอัลกอริทึมหลายอย่างสำหรับสร้างลายเซ็นดิจิทัล เราจึงจำเป็นต้องระบุอัลกอริทึมที่ใช้สำหรับลงนาม JWT การดำเนินการนี้ทำให้สำเร็จได้โดยสร้างวัตถุ JSON:

alg ย่อมาจาก "algorithm" และ typ ย่อมาจาก "type"

โดยทั่วไป typ ถูกตั้งค่าเป็น JWT ด้วยตัวพิมพ์ใหญ่ สำหรับตัวอย่างของเรา alg คือ HS256 ซึ่งย่อมาจาก HMAC-SHA256 (เราจะอธิบายเร็ว ๆ นี้) และระบุว่าเรากำลังใช้สร้างลายเซ็นด้วยอัลกอริทึมนี้

ตอนนี้เรามีทุกองค์ประกอบสำหรับ JWT:

  • Header JSON: อัลกอริทึมและประเภท
  • Payload JSON: ข้อมูลจริง
  • Signature: ลายเซ็นที่ครอบคลุมถึง header และ payload

อย่างไรก็ตาม อักษรบางอย่างเช่นช่องว่างและการขึ้นบรรทัดไม่เป็นมิตรกับการส่งผ่านเครือข่าย ดังนั้น header และ payload จำเป็นต้องถูก เข้ารหัสเป็น Base64URL JWT ทั่วไปดูเหมือนดังนี้:

สัญลักษณ์ . ทำหน้าที่เป็นตัวคั่น

ให้เรารวบรวมทุกสิ่งและสร้าง JWT:

JSON: {"alg":"HS256","typ":"JWT"}

Base64URL เข้ารหัส: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload

JSON: {"sub":"foo","name":"John Doe"}

Base64URL เข้ารหัส: eyJzdWIiOiJmb28iLCJuYW1lIjoiSm9obiBEb2UifQ

Signature

ใน HMAC-SHA256 ลายเซ็นถูกสร้างขึ้นด้วยรหัสลับ:

ยกตัวอย่างเช่น ด้วยรหัสลับ some-great-secret ลายเซ็นจะเป็น: XM-XSs2Lmp76IcTQ7tVdFcZzN4W_WcoKMNANp925Q9g.

JWT

JWT สุดท้ายเป็น:

JWT นี้เป็นจริงและสามารถตรวจสอบได้โดยฝ่ายที่มีรหัสลับ

เลือกอัลกอริทึมการลงนาม

ดังที่กล่าวไว้ก่อนหน้านี้ มีอัลกอริทึมหลายอย่างในการสร้างลายเซ็นดิจิทัล เราได้ใช้ HS256 เป็นตัวอย่าง แต่ก็อาจไม่แข็งแรงพอเนื่องจากรหัสลับต้องถูกแชร์ระหว่างฝ่ายกัน (เช่นไคลเอนต์และเซิร์ฟเวอร์)

ในสถานการณ์จริง ไคลเอนต์อาจประกอบด้วยแอปพลิเคชันสาธารณะเช่นแอปรับที่ไม่สามารถรักษารหัสลับไว้ให้ปลอดภัยได้ ดังนั้นแนวทางที่ต้องการคือการใช้การเข้ารหัสคีย์สาธารณะ (การเข้ารหัสแบบอสมมาตร) สำหรับการลงนามใน JWT ให้เราเริ่มด้วยอัลกอริทึมที่ได้รับความนิยมมากที่สุด: RSA

RSA

RSA, อัลกอริทึมแบบอสมมาตร, ใช้คู่ของกุญแจ: กุญแจสาธารณะและกุญแจส่วนตัว กุญแจสาธารณะใช้ตรวจสอบลายเซ็น ขณะที่กุญแจส่วนตัวใช้ในการลงนาม

Header JSON สำหรับ RSA ดูเหมือนดังนี้:

RS256 ย่อมาจาก RSA-SHA256 ซึ่งหมายความว่าลายเซ็นถูกสร้างด้วยอัลกอริทึม RSA และฟังก์ชันแฮช SHA256 คุณสามารถใช้ RS384 และ RS512 เพื่อสร้างลายเซ็นด้วยฟังก์ชันแฮช SHA384 และ SHA512 ตามลำดับ

ลายเซ็นถูกสร้างขึ้นด้วยกุญแจส่วนตัว:

อีกครั้ง เราสามารถรวบรวมชิ้นส่วนเหล่านี้เพื่อสร้าง JWT และ JWT สุดท้ายจะดูเหมือนดังนี้:

ขณะนี้ไคลเอนต์สามารถตรวจสอบลายเซ็นได้โดยไม่ต้องรู้กุญแจส่วนตัว

ECDSA

แม้ว่า RSA จะถูกใช้อย่างแพร่หลาย แต่ก็มีขนาดของลายเซ็นที่ใหญ่กว่าบางครั้งเกินขนาดรวมของ header และ payload อัลกอริทึมลายเซ็นดิจิทัลวงรี (ECDSA) เป็นอัลกอริทึมอสมมาตรอื่นที่สามารถสร้างลายเซ็นที่กระชับกว่าและมีประสิทธิภาพมากกว่า

ในการสร้างกุญแจส่วนตัวสำหรับ ECDSA เราจำเป็นต้องเลือกเส้นโค้ง สิ่งนี้ไม่เกี่ยวข้องในบทความนี้ แต่คุณสามารถหาข้อมูลเพิ่มเติม ที่นี่

Header JSON สำหรับ ECDSA ดูเหมือนดังนี้:

ES256 ย่อมาจาก ECDSA-SHA256 ซึ่งหมายความว่าลายเซ็นถูกสร้างด้วยอัลกอริทึม ECDSA และฟังก์ชันแฮช SHA256 คุณสามารถใช้ ES384 และ ES512 เพื่อสร้างลายเซ็นด้วยฟังก์ชันแฮช SHA384 และ SHA512 ตามลำดับ

ลายเซ็นถูกสร้างขึ้นด้วยกุญแจส่วนตัว:

JWT สุดท้ายมีโครงสร้างเช่นเดียวกับ RSA แต่ลายเซ็นจะเล็กกว่าอย่างมาก:

ตรวจสอบ JWT

การตรวจสอบ JWT ทำได้ง่ายเหมือนการสร้าง JWT ในทิศตรงข้าม:

  1. แบ่ง JWT ออกเป็นสามส่วน (header, payload, และ signature) โดยใช้ตัวคั่น .
  2. ถอดรหัส header และ payload ด้วย Base64URL
  3. ตรวจสอบลายเซ็นด้วยอัลกอริทึมที่ระบุใน header และกุญแจสาธารณะ (สำหรับอัลกอริทึมอสมมาตร)

มีไลบรารีมากมายที่พร้อมให้ความช่วยเหลือในการตรวจสอบ JWT เช่น jose สำหรับ Node.js และเว็บเบราว์เซอร์

สรุป

ในบทความนี้ เราได้อธิบายแนวคิดพื้นฐานของ JWT สั้น ๆ พร้อมภาพรวมเกี่ยวกับวิธีการสร้างและตรวจสอบ โน๊ตหลายอย่างยังคงไม่ได้สำรวจ และเราจะครอบคลุมในบทความถัดไป

Logto ใช้มาตรฐานเปิดเช่น JWT และ OpenID Connect เพื่อปกป้องแอพและ API ของคุณด้วยเวิร์กโฟลว์ที่ง่ายขึ้นสำหรับนักพัฒนาทุกคน หากคุณสนใจ คุณสามารถลองได้ฟรี (ไม่ต้องใช้บัตรเครดิต)