• OAuth
  • client
  • public
  • confidential
  • PKCE

ความแตกต่างระหว่างลูกค้าแบบสาธารณะและที่เป็นความลับคืออะไร?

บทความนี้เปิดเผยความแตกต่างระหว่างลูกค้าแบบสาธารณะและที่เป็นความลับใน OAuth โดยใช้ตัวอย่างแอปพลิเคชัน Logto

Darcy Ye
Darcy Ye
Developer

เมื่อใช้ Logto เพื่อสร้างแอปพลิเคชัน คุณจะสังเกตได้ว่ามีประเภทแอปพลิเคชันหลายประเภทให้เลือก รวมถึง Single Page Application (SPA), Native App และ Traditional Web App โดยปกติแล้ว จากชื่อ จะเห็นได้ชัดว่า Native App ทำงานบนระบบปฏิบัติการที่มักพบในอุปกรณ์ เช่น โทรศัพท์ อย่างไรก็ตาม SPA และ Traditional Web App คืออะไร? ทำไมเราจึงต้องแยกประเภทแอปพลิเคชันเหล่านี้? บทความนี้จะเปิดเผยคำตอบของคำถามเหล่านี้

ก่อนเริ่มต้น เราต้องให้คำแนะนำเกี่ยวกับแนวคิดบางอย่าง

OAuth คืออะไร?

OAuth เป็นมาตรฐานการอนุญาตแบบเปิด ที่ใช้ในการอนุญาตให้ผู้ใช้ผ่านทางอินเทอร์เน็ตให้เว็บไซต์หรือแอปพลิเคชันเข้าถึงข้อมูลของพวกเขาในเว็บไซต์อื่น ๆ โดยไม่ต้องให้รหัสผ่านของพวกเขา

ในทศวรรษที่ผ่านมา มันค่อยๆ กลายเป็นกระบวนการอนุญาตมาตรฐานและได้รับการยอมรับอย่างกว้างขวางจากบริษัทต่างๆ เช่น Google, Meta, Microsoft เป็นต้น ปัจจุบันเวอร์ชันที่ใช้อยู่คือ OAuth 2.0

ในบริบทของ OAuth แอปพลิเคชันที่เรากล่าวถึงก่อนหน้านี้เรียกว่า Client พวกเขาสามารถส่งคำขอสำหรับทรัพยากรที่ได้รับการป้องกันได้ ตราบใดที่ได้รับการอนุญาตจากเจ้าของทรัพยากร (มักเป็นผู้ใช้งานปลายทาง)

ลูกค้าแบบสาธารณะและลูกค้าแบบที่เป็นความลับ

OAuth กำหนดประเภทของลูกค้าสองประเภท ขึ้นอยู่กับความสามารถในการรักษาความลับของข้อมูลรับรองลูกค้า

ลูกค้าที่เป็นความลับ

ลูกค้าที่สามารถรักษาความลับของข้อมูลรับรองตัวเองได้ (เช่น ลูกค้าที่นำไปใช้บนเซิร์ฟเวอร์ที่มีการควบคุมการเข้าถึงข้อมูลรับรองลูกค้า) หรือเป็นลูกค้าที่สามารถทำการยืนยันความปลอดภัยของลูกค้าผ่านวิธีการอื่นได้

ลูกค้าแบบสาธารณะ

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

SPA, แอปพลิเคชันพื้นเมือง, และแอปพลิเคชันเว็บแบบดั้งเดิม

ด้วยความรู้พื้นฐานที่กล่าวมาข้างต้น ลองพิจารณาดูว่า SPA, แอปพื้นเมือง, และแอปพลิเคชันเว็บแบบดั้งเดิม หมายถึงอะไรในบริบทของ Logto รวมถึงว่าเป็นลูกค้าแบบสาธารณะหรือลูกค้าที่เป็นความลับ

SPA

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

แอปพื้นเมือง

แอปพื้นเมืองจะติดตั้งและทำงานบนอุปกรณ์ของเจ้าของทรัพยากร ข้อมูลของโพรโตคอลและข้อมูลรับรองจะสามารถเข้าถึงได้โดยเจ้าของทรัพยากร โดยทั่วไปแล้ว สมมติว่าข้อมูลรับรองการยืนยันตัวตนของลูกค้าที่มีอยู่ภายในแอปพลิเคชันสามารถถูกดึงมาได้

แอปพลิเคชันเว็บแบบดั้งเดิม

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

ดังนั้น เราจะเห็นได้อย่างชัดเจนว่า SPA และแอปพื้นเมืองเป็นลูกค้าแบบสาธารณะ ในขณะที่แอปพลิเคชันเว็บแบบดั้งเดิมเป็นลูกค้าที่เป็นความลับ

คุณอาจพบว่าขณะสร้าง SPA หรือแอปพื้นเมืองใน Logto ไม่มีรหัสลับของแอป ในขณะที่แอปพลิเคชันเว็บแบบดั้งเดิมมีทั้ง App ID และรหัสลับของแอป นี้เป็นเพราะความลับของลูกค้าแบบสาธารณะไม่สามารถรับรองได้ว่าจะปลอดภัย

ลูกค้าทำงานอย่างไรในกระบวนการอนุญาต OAuth?

เมื่อพัฒนาแอปพลิเคชัน OAuth ขั้นตอนแรกคือการลงทะเบียนลูกค้ากับผู้ให้บริการ OAuth การลงทะเบียนลูกค้ารวมถึงการให้รายละเอียดเกี่ยวกับแอปพลิเคชัน เช่น ชื่อและ Redirect URI จากนั้น ผู้ให้บริการ OAuth จะสร้าง client ID และ client secret ซึ่งถือว่าเป็นข้อมูลรับรองของแอปพลิเคชัน

client ID ถือว่าเป็นข้อมูลสาธารณะและจะแชร์กับผู้ใช้ระหว่างกระบวนการ OAuth โดยปกติแล้วจะรวมอยู่ใน URL การอนุญาตและมองเห็นได้กับผู้ใช้งานปลายทาง

ในทางกลับกัน client secret ทำหน้าที่เป็นรหัสผ่านของแอปพลิเคชันและต้องรักษาเป็นความลับ มันใช้ในการแลกเปลี่ยน authorization code ในกระบวนการ OAuth (สมมติว่ามันเป็น authorization code flow) เพื่อให้ได้โทเค็นการเข้าถึง การมีอยู่ของ client secrets ยังให้แน่ใจว่าเฉพาะแอปพลิเคชันที่ลงทะเบียนแล้วสามารถทำการแลกเปลี่ยนโทเค็นการเข้าถึงได้

การแนะนำ Proof Key for Code Exchange (PKCE)

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

PKCE (Proof Key for Code Exchange) แก้ปัญหานี้โดยการสร้าง code verifier ชั่วคราวในช่วงเริ่มต้นของแต่ละกระบวนการอนุญาต ซึ่งจัดเก็บไว้ในเครื่องและแฮชเพื่อสร้าง code challenge ที่ถูกส่งไปยังเซิร์ฟเวอร์การอนุญาต code verifier จะถูกส่งอีกครั้งไปยังเซิร์ฟเวอร์การอนุญาต เมื่อแลกเปลี่ยนโทเค็นการเข้าถึง เซิร์ฟเวอร์การอนุญาตตรวจสอบว่า code verifier และ code challenge ตรงกัน เพื่อให้แน่ใจว่าลูกค้าสาธารณะไม่ได้ถูกแอบอ้าง

code verifier ใน PKCE ทำงานจริง ๆ เป็นความลับของลูกค้าแบบไดนามิก ความปลอดภัยของมันได้รับจากการไม่สามารถย้อนกลับของอัลกอริธึมแฮช

สรุป

ในบทความนี้ เราได้พูดคุยเกี่ยวกับแนวคิดของลูกค้าที่เป็นความลับและลูกค้าแบบสาธารณะใน OAuth เราได้เรียนรู้ว่าลูกค้าที่เป็นความลับมีความสามารถในการรักษาความลับและจัดเก็บข้อมูลที่เป็นความลับอย่างปลอดภัย ในขณะที่ลูกค้าแบบสาธารณะขาดความสามารถนี้ เราได้ตรวจสอบตัวอย่างของลูกค้าทั้งสองประเภท รวมถึงแอปพลิเคชันเว็บแบบดั้งเดิม, SPA และแอปพื้นเมืองในบริบทของการปฏิบัติผลิตภัณฑ์ของ Logto

เรายังได้สนทนาเกี่ยวกับกระบวนการลงทะเบียนลูกค้าใน OAuth และบทบาทของ client ID และ client secret

ยิ่งไปกว่านั้น เรายังพบว่าลูกค้าแบบสาธารณะเผชิญข้อจำกัดในการจัดเก็บ client secrets อย่างปลอดภัย การเอาชนะข้อจำกัดนี้ เราได้แนะนำ PKCE (Proof Key for Code Exchange) ซึ่งเป็นส่วนขยายของ OAuth ที่ช่วยให้ลูกค้าแบบสาธารณะสามารถแลกเปลี่ยน authorization codes ได้อย่างปลอดภัยโดยไม่ต้องใช้ client secret

ผลิตภัณฑ์ของเรา Logto เป็นโซลูชัน CIAM ที่ครบวงจรที่ปฏิบัติตามแนวทางที่ดีที่สุดของโปรโตคอล OAuth และ OIDC เพื่อให้มั่นใจในความปลอดภัยในทุกขั้นตอน รวมถึงการนำ PKCE มาใช้เพื่อปกป้องความปลอดภัยของลูกค้าแบบสาธารณะ