ถอดรหัส JWT
ถอดรหัสและตรวจสอบ JSON Web Token
JWT Token
JWT (JSON Web Token) คืออะไร?
JSON Web Token (JWT) คือรูปแบบโทเค็นที่กระชับและปลอดภัยสำหรับ URL ซึ่งกำหนดไว้ใน RFC 7519 โดยจะเข้ารหัสชุด claims เป็นออบเจกต์ JSON จากนั้นลงนาม — และเข้ารหัสข้อมูลเพิ่มเติมตามต้องการ — เพื่อให้ผู้รับสามารถยืนยันได้ว่าข้อมูลไม่ถูกแก้ไข JWT เป็นมาตรฐานโดยพฤตินัยสำหรับการตรวจสอบตัวตนแบบไร้สถานะใน REST API ระบบ single sign-on และการอนุญาตไมโครเซอร์วิส
โครงสร้าง JWT: Header · Payload · Signature
JWT ทุกตัวประกอบด้วยสามส่วนที่เข้ารหัส base64url คั่นด้วยจุด Header และ Payload เป็น JSON ธรรมดา — ใครก็อ่านได้ — ในขณะที่ Signature เป็นค่าเข้ารหัสที่สามารถยืนยันได้ด้วยคีย์ที่ถูกต้องเท่านั้น
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkFsaWNlIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzE3MjAwMDAwLCJleHAiOjE3MTcyMDM2MDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
{
"alg": "HS256",
"typ": "JWT"
}{
"sub": "user123",
"name": "Alice",
"role": "admin",
"iat": 1717200000,
"exp": 1717203600
}ทำไมต้องใช้ JWT Decoder?
JWT ดิบดูเหมือนข้อความสุ่ม เครื่องมือนี้แสดง Header และ Payload ในรูป JSON ที่จัดรูปแบบทันที เพื่อให้คุณตรวจสอบ claims ดูเวลาหมดอายุ และตรวจสอบการเลือกอัลกอริทึมโดยไม่ต้องเขียนโค้ดแม้แต่บรรทัดเดียว
การอ้างอิง JWT Claims มาตรฐาน
RFC 7519 กำหนดชื่อ claim ที่ลงทะเบียนไว้เจ็ดรายการ ไม่บังคับให้ใช้ แต่แนะนำอย่างยิ่งเพื่อให้สามารถทำงานร่วมกันได้ คุณสามารถเพิ่ม claim ที่กำหนดเองใน Payload ได้
| Claim | คำอธิบาย | ประเภท |
|---|---|---|
| iss | ผู้ออกโทเค็น — ระบุว่าใครเป็นผู้ออกโทเค็น เช่น URL ของเซิร์ฟเวอร์ตรวจสอบตัวตนหรือชื่อแอปพลิเคชัน | string |
| sub | หัวข้อ — ระบุหน่วยงานที่ JWT เกี่ยวข้อง โดยทั่วไปคือ ID ผู้ใช้หรือบัญชีบริการ | string |
| aud | กลุ่มเป้าหมาย — ระบุผู้รับที่ตั้งใจไว้ ฝ่ายรับต้องยืนยันว่าตรงกับตัวระบุของตน | string | string[] |
| exp | เวลาหมดอายุ — Unix timestamp ที่หลังจากนั้นไม่ควรยอมรับโทเค็น ควรตั้งค่านี้เสมอเพื่อจำกัดความเสียหายจากโทเค็นที่ถูกขโมย | number |
| nbf | ไม่ก่อนหน้านี้ — Unix timestamp ที่ก่อนหน้านั้นไม่ควรยอมรับโทเค็น มีประโยชน์สำหรับการกำหนดเวลาโทเค็นที่มีวันที่ในอนาคต | number |
| iat | ออกเมื่อ — Unix timestamp ที่ออกโทเค็น ใช้เพื่อคำนวณอายุของโทเค็น | number |
| jti | JWT ID — ตัวระบุเฉพาะสำหรับโทเค็น ช่วยให้สามารถยกเลิกได้โดยการจัดเก็บและตรวจสอบค่า JTI ที่ใช้ไปแล้วฝั่งเซิร์ฟเวอร์ | string |
อัลกอริทึมการลงนาม JWT
claim ส่วนหัว alg ประกาศว่าอัลกอริทึมใดลงนามโทเค็น การเลือกส่งผลต่อความปลอดภัย ประสิทธิภาพ และว่าบริการของบุคคลที่สามสามารถยืนยันโทเค็นโดยไม่มีคีย์ส่วนตัวหรือไม่
| อัลกอริทึม | ตระกูล | ประเภทคีย์ | หมายเหตุ |
|---|---|---|---|
| HS256 | HMAC | Symmetric | พบบ่อยที่สุด ความลับที่ใช้ร่วมกัน — ผู้ที่มีความลับสามารถลงนามและยืนยันได้ |
| HS384 | HMAC | Symmetric | HMAC ที่แข็งแกร่งกว่า ต้นทุนประสิทธิภาพปานกลาง |
| HS512 | HMAC | Symmetric | HMAC ที่แข็งแกร่งที่สุด |
| RS256 | RSA | Asymmetric | อัลกอริทึมแบบอสมมาตรที่ใช้กันมากที่สุด (Google, Auth0, Okta) คีย์สาธารณะยืนยันได้โดยไม่ต้องใช้คีย์ส่วนตัว |
| RS384 | RSA | Asymmetric | RS ที่มีความปลอดภัยสูงกว่า |
| RS512 | RSA | Asymmetric | RS ที่แข็งแกร่งที่สุด |
| ES256 | ECDSA | Asymmetric | เส้นโค้งวงรี ลายเซ็นสั้นกว่า RSA เป็นที่นิยมบนมือถือและ IoT |
| PS256 | RSA-PSS | Asymmetric | RSA-PSS: ทันสมัยและปลอดภัยกว่า RS256 ที่ใช้ PKCS1v1.5 |
| none | — | — | ไม่มีลายเซ็น — อันตรายอย่างยิ่ง อย่ายอมรับโทเค็นที่มี alg: none ในระบบจริงเด็ดขาด |
ข้อควรพิจารณาด้านความปลอดภัย
การถอดรหัส JWT ปลอดภัยเสมอ แต่การเชื่อถือ JWT โดยไม่ตรวจสอบลายเซ็นที่ถูกต้องนั้นไม่ปลอดภัย โปรดจำกฎเหล่านี้ทุกครั้งที่ใช้โทเค็นในแอปพลิเคชันของคุณ
- –ถอดรหัสและตรวจสอบ JWT ในเครื่องมือสำหรับนักพัฒนาหรือเครื่องมือนี้
- –ใช้ exp, iat และ nbf เพื่อทำความเข้าใจอายุของโทเค็น
- –บันทึก claims ใน Payload เพื่อดีบัก (ละเว้นข้อมูลส่วนตัวที่ละเอียดอ่อน)
- –อ่าน header alg เพื่อทำความเข้าใจวิธีการลงนามโทเค็น
- –เชื่อถือ claims ใน Payload โดยไม่ตรวจสอบลายเซ็นฝั่งเซิร์ฟเวอร์
- –ยอมรับโทเค็นที่มี alg: none ซึ่งหมายความว่าไม่มีลายเซ็นเลย
- –จัดเก็บ access token ใน localStorage บนแอปพลิเคชันที่มีความปลอดภัยสูง (ควรใช้ cookie httpOnly แทน)
- –ตั้งค่า exp ไว้ในอนาคตอันไกลโพ้นสำหรับโทเค็นที่มีสิทธิ์ละเอียดอ่อน
กรณีการใช้งานทั่วไป
การถอดรหัส JWT ในโค้ด
Header และ Payload ถูกเข้ารหัส base64url เพียงแค่กลับการเข้ารหัส Base64url แทน + ด้วย - และ / ด้วย _ และไม่มีการเติม = เฉพาะ Signature เท่านั้นที่ต้องการคีย์ลับ
function decodeJWT(token) {
const [, payload] = token.split('.')
const json = atob(payload.replace(/-/g, '+').replace(/_/g, '/'))
return JSON.parse(json)
}const [, payload] = token.split('.')
const decoded = JSON.parse(
Buffer.from(payload, 'base64url').toString()
)import base64, json
def decode_jwt(token):
payload = token.split('.')[1]
padding = '=' * (-len(payload) % 4)
return json.loads(base64.urlsafe_b64decode(payload + padding))TOKEN="eyJhbGc..." echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | jq .