JSON Web Token (JWT) คืออะไร?
ทำความเข้าใจพื้นฐานของ JSON Web Token (JWT) อย่างชัดเจนในเวลา 5 นาที
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:
Header
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 ในทิศตรงข้าม:
- แบ่ง JWT ออกเป็นสามส่วน (header, payload, และ signature) โดยใช้ตัวคั่น
.
- ถอดรหัส header และ payload ด้วย Base64URL
- ตรวจสอบลายเซ็นด้วยอัลกอริทึมที่ระบุใน header และกุญแจสาธารณะ (สำหรับอัลกอริทึมอสมมาตร)
มีไลบรารีมากมายที่พร้อมให้ความช่วยเหลือในการตรวจสอบ JWT เช่น jose สำหรับ Node.js และเว็บเบราว์เซอร์
สรุป
ในบทความนี้ เราได้อธิบายแนวคิดพื้นฐานของ JWT สั้น ๆ พร้อมภาพรวมเกี่ยวกับวิธีการสร้างและตรวจสอบ โน๊ตหลายอย่างยังคงไม่ได้สำรวจ และเราจะครอบคลุมในบทความถัดไป
Logto ใช้มาตรฐานเปิดเช่น JWT และ OpenID Connect เพื่อปกป้องแอพและ API ของคุณด้วยเวิร์กโฟลว์ที่ง่ายขึ้นสำหรับนักพัฒนาทุกคน หากคุณสนใจ คุณสามารถลองได้ฟรี (ไม่ต้องใช้บัตรเครดิต)