[JWT != OAuth2 != OpenID Connect]

Natechawin Suthison
2 min readOct 12, 2023

--

เรื่องนี้เป็นเรื่องที่ผมเจอว่าคนเข้าใจผิดกันบ่อยมากๆ ล่าสุดคือตอนคุยกับคุณลูกค้าธนาคารยักษ์ใหญ่เจ้าหนึ่งว่า เราจะใช้ JWT format เป็น token สำหรับทำ server to server authen นะ คุยกันอยู่พักใหญ่ๆก็มีฝั่ง tech ของลูกค้าถามขึ้นมาว่า ที่เราจะใช้คือ OAuth2 ใช่ไหม ต่อไปนี้เวลาคุยให้เรียกว่า OAuth2 ได้ไหม เรียกว่า JWT แล้วหลายๆคนงง ก็เลยต้องอธิบายกันว่า เราเรียกว่า OAuth2 ไม่ได้นะ เพราะเราไม่ได้จะทำ OAuth แต่จะใช้แค่ JWT ไง!

จริงๆนอกจากคุณลูกค้าเจ้านี้ เวลาคุยกันเรื่องการทำ Authentication (การยืนยันตัวตนว่า ตัวตนที่คุณอ้างถึงน่ะคือคุณจริงๆนะ) กับการ Authorization (คุณมีสิทธิ์ในการเข้าถึงหรือกระทำการใดๆต่อข้อมูลหนึ่งๆไหม) ก็ดูจะมีคนสับสนและจับสองคำนี้มาผสมปนกันเยอะพอสมควร

.

.

JWT vs OAuth2 vs OpenID Connect

JWT เป็น self-contain token format แปลว่าเป็น token format ที่สามารถ store data ไว้ในตัวมันเองได้ โดยที่ใครๆก็สามารถแกะ data ออกมาดูได้ แต่ไม่สามารถเปลี่ยนแปลงแก้ไขได้ เพราะ token ถูก sign ไว้ด้วย digital signature (คือแก้ได้แหละ แต่ตอน verify คนถือ secret key จะรู้ว่า data ถูกแก้หรือไม่)

OAuth2 เป็น standard authorization protocol ที่ทำให้ application หนึ่งๆสามารถขอสิทธิ์ (Authorize) ในการ access ข้อมูลใดๆตามที่ user (resource owner) อนุญาตจากอีก application หนึ่งได้ และใน flow ของ protocol นี้จำเป็นต้องมีการแลกเปลี่ยน access token ซึ่งคนมักจะใช้ JWT เป็น format ของ access token นั้น ซึ่ง access token ของ OAuth ไม่จำเป็นต้องเป็น JWT จาก [RFC6749](https://datatracker.ietf.org/doc/html/rfc6749) จะเห็นว่าเค้าไม่ได้กำหนดเลยว่า Token จะต้องเป็น format อะไร

OpenID Connect (OIDC) เป็น standard authentication protocol ที่เป็น Layer build on top อยู่บน OAuth อีกที เพื่อที่ให้ application หนึ่งๆ (Relying Party) สามารถยืนยันตัวตนของ User จากอีก application หนึ่งได้ (OpenID provider) สังเกตุว่า OAuth เป็น Standard สำหรับ `Authorization` ในขณะที่ Open ID Connect เป็น standard สำหรับ `Authentication` และในขณะที่ OAuth ไม่ได้ specific token format, OpenID Connect specify ไว้ชัดเจนว่าใช้ JWT ดูได้จาก [OpenID Connect 1.0 core](https://openid.net/specs/openid-connect-core-1_0.html)

.
.

โดยสรุป JWT เป็นแค่ Token Format ขณะที่ OAuth คือการขอ/ให้สิทธิ์ (Authorization) เหมือนเวลาที่เรากดเข้าแอพซักแอพนึง แล้วแอพนั้นขอสิทธิ์เราในการเข้าถึงเพื่อนบน facebook หรือขอรู้จักเพื่อนๆเราใน email list ของ gmail ส่วน OIDC คือเหมือนเวลาที่เราจะ login website ใดๆ แล้วมี option ให้เรา login ด้วย google, facebook, หรือ apple โดยที่เราไม่ต้องสมัครกับ website นั้นๆ แต่สามารถยืนยันตัวตน (Authentication) ของเราผ่าน 3rd party อย่าง google, facebook, หรือ apple ได้เลย

ถามว่า OAuth ทำ Authentication Flow ได้ไหม คำตอบคือได้โดยต้องไปเพิ่มนู่นนิดเพิ่มนี่หน่อย แต่ความเห็นส่วนตัวคือมันเป็น Hacky way คือ OAuth ไม่ได้เกิดมาเพื่อทำ Authentication การทำ Authentication บน OAuth เลยถูกเรียกว่าเป็น Pseudo-Authentication ถ้าอยากจะทำ Authentication ให้ follow OIDC ดีกว่า เป็น international standard มากกว่า

ผมคิดว่าการเข้าใจและแยกสามอย่างนี้ออกจากกันได้สำคัญนะ มันจะทำให้เราเห็นภาพแยกเป็นก้อนๆว่าแต่ละอันทำหน้าที่อะไร สามารถเลือกใช้ได้เหมาะสมตามงาน (อย่างเช่นงานของคุณลูกค้าข้างบน เป็นการทำ server to server authen ง่ายๆ ใช้ token คุยกันก็เพียงพอ) และสามารถ implement แต่ละส่วนได้ถูกต้อง สามารถประยุกต์ใช้ได้เมื่อจำเป็น ไม่งั้นเราก็จะแค่ follow ตาม protocol ไปเฉยๆโดยที่ไม่เข้าใจอะไร และ boundary ของเจ้าสามตัวนี้จะ blurly มาก อาจจะทำให้เราออกแบบมันและ/หรือ implement มันออกมา tight couple โดยไม่รู้ตัว

Ref: My original post

--

--