

JWT ที่ส่งมากับคำขอสามารถถูกเปิดอ่าน payload ได้ง่ายในหลายกรณี พอเห็นชื่อผู้ใช้ role หรือเวลาหมดอายุอยู่ข้างใน ก็อาจเผลอใช้ข้อมูลนั้นตัดสินสิทธิ์ทันที ทั้งที่ยังไม่ได้ตรวจว่าผู้ส่งแก้ข้อความมาหรือไม่
ความสะดวกในการพกข้อมูลไม่ใช่ความเชื่อถือในข้อมูลนั้นเอง การ decode มีหน้าที่อ่านรูปแบบ ส่วนการ verify และการตรวจเงื่อนไขผู้รับเป็นอีกขั้นที่ต้องกำหนดตามชนิด token กับระบบที่ออกให้
ควรแยกการอ่าน การรับรองและการอนุญาตให้ชัดครับ เพราะ token ที่ลายเซ็นถูกต้องก็ยังอาจไม่ใช่ token สำหรับ API นี้หรือไม่ให้สิทธิ์กับรายการที่ขออยู่
JWT เป็นรูปแบบพก claims ซึ่งอาจถูกลงนามหรือเข้ารหัสตามกลไกที่ใช้ กรณีที่พบเป็นข้อความสามส่วนมักเป็นรูปแบบ compact ของ JWS แต่ไม่ควรเหมารวมว่า JWT ทุกแบบต้องมีสามส่วนและอ่านได้เหมือนกันทั้งหมด
สำหรับ JWS ที่ payload ไม่ได้ถูกเข้ารหัส การแปลง base64url ช่วยอ่านข้อมูลได้โดยไม่ได้มีความลับในการถอด ความสามารถนี้จึงไม่ได้พิสูจน์ว่าข้อมูลถูกต้อง และการลงนามก็ไม่ได้ทำให้ข้อความใน payload กลายเป็นข้อมูลลับ
จึงควรเลือก claims เท่าที่งานต้องใช้ ไม่ใส่ password secret หรือข้อมูลที่ผู้ถือ token ไม่ควรอ่านแล้วหวังว่าเนื่องจากมันไม่ใช่ JSON ตรงๆ คนจะเปิดไม่ออก หากต้องรักษาความลับ ต้องออกแบบกลไกกับทางส่งตามข้อกำหนดแยกจากการตรวจความแท้
เครื่องมือ decode มีประโยชน์ตอนพัฒนา แต่ไม่ควรนำ token จริงไปวางในเว็บหรือรายงานที่ไม่อยู่ในขอบเขตดูแล ควรใช้ตัวอย่างที่สร้างเพื่อทดสอบและไม่มีข้อมูลรับรองจริง เพื่อไม่ให้ขั้น debug กลายเป็นช่องส่งต่อสิทธิ์ให้คนอื่น

Verifier ต้องรู้ว่าจะรับอัลกอริทึมใดและใช้กุญแจที่สัมพันธ์กับผู้ออกตามสัญญา ไม่ปล่อยให้ค่า alg ที่ผู้ส่งใส่มาเป็นผู้เลือกได้อิสระว่าควรตรวจอย่างไรหรือไม่ต้องตรวจเลย
RFC8725 ระบุให้ implementation เปิดทางกำหนดชุดอัลกอริทึมที่รองรับและไม่ใช้สิ่งอื่นนอกชุดนั้น รวมถึงความสอดคล้องของกุญแจกับอัลกอริทึม การใช้ library จึงยังต้องตั้งค่าฝั่งผู้รับให้ถูก ไม่ใช่เรียกชื่อฟังก์ชัน verify แล้วถือว่ามีนโยบายครบแล้ว
ค่า kid ใช้ช่วยเลือกกุญแจได้ตามระบบ แต่ยังเป็น input ที่ต้องจำกัดกับแหล่งที่เชื่อถือ ไม่เอาไปต่อเป็น path หรือ query โดยไม่ตรวจ และไม่ตาม URL ของชุดกุญแจที่ token เสนอมาเองโดยไม่จำกัดขอบเขต
หากใช้กุญแจสาธารณะจากผู้ออก ต้องมีวิธีผูก issuer กับชุดกุญแจที่ถูกต้อง พร้อมนโยบาย refresh และหมุนกุญแจตามอายุ token ไม่ใช้กุญแจที่เพิ่งค้นเจอจากแหล่งใดก็ได้เป็นหลักฐานว่าลายเซ็นผ่านแล้วควรยอมรับ
Issuer บอกผู้ออกตามสัญญา ส่วน audience ใช้ระบุผู้รับที่ token ตั้งใจให้ใช้ ระบบที่มีหลาย API หรือหลาย environment จึงต้องตรวจว่า token อยู่ในบริบทที่ตนยอมรับ ไม่ใช้เพียงกุญแจร่วมกันแล้วรับทุกใบที่ตรวจผ่าน
ตัวอย่างสมมติคือผู้ใช้ได้ token สำหรับบริการรายงาน แต่ส่งมาที่ API จัดการบัญชี หากทั้งสองใช้ผู้ออกเดียวกัน การตรวจลายเซ็นอย่างเดียวอาจไม่แยกว่ามันไม่ได้ถูกออกมาให้ผู้รับนี้ ต้องมี audience และเงื่อนไขของชนิด token ที่ชัด
Subject ก็ต้องสัมพันธ์กับตัวตนในระบบที่รับ ไม่ตีความเลขผู้ใช้จาก issuer หนึ่งเป็นบัญชีเดียวกับอีก issuer เพียงเพราะค่า sub เหมือนกัน และไม่ใช้ display name แทนตัวระบุที่สัญญากำหนด
สำหรับระบบที่ใช้ token หลายหน้าที่ ควรมี validation rule ที่แยกกันตามชนิด เช่น token สำหรับการยืนยันผลบางอย่างไม่ควรถูกนำไปใช้เป็น access token ทั่วไป การมีชื่อ claim คล้ายกันไม่ได้ให้ความหมายเดียวกันทุก protocol

Claims อย่าง exp และ nbf มีความหมายเรื่องเวลาหมดอายุกับเวลาที่ยังไม่ให้ใช้ตามข้อกำหนด แต่แอปต้องระบุว่าชนิด token ที่รับจำเป็นต้องมีค่าใดบ้าง ไม่สรุปว่ารูปแบบ JWT บังคับทุก claim ที่ผลิตภัณฑ์ต้องการให้อัตโนมัติ
เมื่อต้องใช้ exp ต้องไม่ยอมรับหลังถึงกำหนดตามการตรวจที่เกี่ยวข้อง และหากเผื่อ clock skew ก็ต้องจำกัดตามความต้องการจริง ไม่ขยายเวลาเพื่อแก้อาการนาฬิกาของระบบโดยไม่มีขอบเขต
ค่า iat บอกเวลาที่ออกตามความหมายของมัน ไม่ใช่ตัวแทน exp โดยอัตโนมัติ และค่าเวลาที่อ่านได้จาก token ที่ยังไม่ได้ verify ก็ยังเป็นข้อความที่ผู้ส่งให้มา ต้องไม่ใช้เป็นเหตุข้ามการตรวจขั้นอื่น
ควรทดสอบกรณีขาด claim ที่นโยบายต้องมี เวลายังไม่ถึง หมดอายุ และชนิดค่าผิดด้วย ไม่ตรวจเฉพาะ token ที่เครื่องมือสร้างให้ในทางสำเร็จเพียงกรณีเดียว
การยืนยันว่าผู้ขอเป็นใครกับการให้สิทธิ์รายการที่ขอเป็นอีกขั้น หาก token ระบุ role หนึ่ง ยังต้องตรวจการเป็นเจ้าของ tenant หรือเงื่อนไข resource ตามแบบจำลองของแอป ไม่ใช้ชื่อ role เป็นทางผ่านทุก ID ที่ client ส่งมา
สิทธิ์ใน token ยังอาจเป็นภาพตอนออกใบ หากบัญชีถูกระงับหรือสิทธิ์เปลี่ยนก่อนหมดอายุ ต้องมีนโยบายว่าระบบจะรับรู้อย่างไรตามความเสี่ยง การมีลายเซ็นไม่ได้ดึงข้อมูลสถานะล่าสุดของบัญชีมาให้เอง
การใส่ jti ช่วยให้มีตัวระบุ token แต่ไม่ได้สร้างระบบเพิกถอนในตัว และการลบ token ออกจากหน้าจอหนึ่งก็ไม่ได้ทำให้สำเนาที่คนอื่นถือหมดผลบน server ถ้าผู้รับยังยอมรับมันตามกติกาเดิม
ควรทดสอบด้วยกุญแจและบัญชีแยกจาก production ทั้ง token ที่ลายเซ็นผิด issuer ผิด audience ผิด ชนิดผิดและสิทธิ์ resource ไม่ผ่าน แล้วอ่านว่าระบบปฏิเสธตามเหตุโดยไม่แสดงข้อมูลภายในเกินจำเป็น ใช้ตัวตรวจของ library ที่ดูแลอยู่แทนเขียน crypto verifier ขึ้นเอง
Decode JWT ช่วยอ่านข้อมูล แต่ความเชื่อถือต้องมาจากการ verify ด้วยกุญแจและกติกาที่ถูก พร้อมตรวจ issuer audience ชนิดและเวลาตามสัญญา จากนั้นยังต้องตัดสินสิทธิ์ของงานกับ resource เมื่อแยกแต่ละชั้นได้ เราจะใช้ token พก claims ได้สะดวกโดยไม่ปล่อยให้ข้อความที่อ่านออกกลายเป็นสิทธิ์ที่ยังไม่เคยตรวจ