ต่อ API กับ KBank — มาต่อกันกับ EP.2 การยืนยันตัวตนผ่าน OAuth 2.0

Oat Chayakorn
KBTG Life
Published in
5 min readJan 21, 2021

จากบทความใน EP.1 เราได้กล่าวถึงพื้นฐานการเชื่อมต่อ API รวมถึงการรับส่งผ่าน Two Way SSL กันไปแล้ว เพื่อเพิ่มความเข้าใจเกี่ยวกับมาตรฐานด้านความปลอดภัยในการยืนยันตัวตนที่ KBank ใช้เป็นมาตรฐานให้กับ Partner Application หรือผู้สนใจต้องการเข้ามาเชื่อมต่อสามารถปฏิบัติตามได้อย่างถูกต้อง ผมจึงขอนำเสนอบทความตอนที่ 2 นี้เป็นแนวทางในการยืนยันตัวตนผ่าน OAuth 2.0 ครับ

Photo from https://www.slideshare.net/ngzm/oauth-10-oauth-20-openid-connect

OAuth 2.0 คืออะไร ?

OAuth 2.0 คือ Authorization Framework ที่กำหนดรูปแบบการให้สิทธิ์การเข้าถึง Resource กับ Third-Party Application ผ่าน HTTP Service ไม่ว่าจะเป็นการเข้าถึงในนามของ Resource Owner หรือเข้าถึงข้อมูลในนามของ Third-Party Application เองก็ตาม

สำหรับรายละเอียดเพิ่มเติม ผมขอแนะนำให้ลองเข้าไปอ่านที่ IETF OAuth 2.0 Specification กันดูนะครับ

OAuth 2.0 Concept

เพื่อให้เห็นภาพใหญ่ รวมถึงหลักการทำงานของ OAuth 2.0 ขออนุญาตอธิบายผ่าน แผนภาพด้านล่างนี้เพื่อให้เข้าใจตรงกันครับ

Photo from https://docs.apigee.com/api-platform/security/oauth/oauth-introduction

สิ่งที่ควรรู้จักภายใต้คอนเซ็ปต์ OAuth 2.0

  1. Client ในที่นี้ก็คือแอปพลิเคชัน อาจจะเป็น Mobile App, Web App หรือแอปใดๆ ก็ได้ที่ต้องการส่งคำร้องขอไปหา Resource Server เพื่อเข้าถึง Resource ที่ถูกปกป้องไว้ในนามของ Resource Owner (หรือในนามของแอปเอง)
  2. Resource Owner คือ End User ที่เป็นเจ้าของข้อมูลและมีสามารถมอบสิทธิ์การเข้าถึง Resource ให้กับแอป Client ในการเข้าถึงข้อมูลที่ตนเองถือสิทธิ์อยู่
  3. Resource Server เป็น Service Provider ที่ให้บริการ API รวมถึงการเข้าถึงข้อมูลต่างๆ ตามสิทธิ์ที่มีผ่านตัว Access Token
  4. Authorization Server ระบบจัดการสิทธิ์การเข้าถึง โดยจะทำการตรวจสอบสิทธิ์ตาม “Authorization Grants” และเป็นผู้ออก Access Token เพื่อให้แอปใช้ในการเข้าถึง Resource ที่ต้องการได้ภายในเวลาที่ทางระบบกำหนดไว้
  5. Authorization Grant เป็นรูปแบบการอนุญาต/ให้สิทธิ์กับแอป โดย OAuth 2.0 จะมีรูปแบบหลักๆ อยู่ 4 รูปแบบ “Grant Types” ซึ่งจะอธิบายในหัวข้อต่อไป
  6. Access Token เป็นชุด Character ขนาดยาว ทำหน้าที่เป็น Credential เพื่อใช้ในการเข้าถึง Resource ที่กำหนด Token ดังกล่าวจะถูกออกโดย Authorization Server เท่านั้น

หากให้อธิบายโดยสังเขป คือเมื่อเรามีแอปพลิเคชันที่ต้องการเข้าถึง API ผ่าน Resource Server การตรวจสอบสิทธิ์ในการเข้าถึงถือเป็นเรื่องสำคัญ เพื่อปกป้องข้อมูลและ Resource ของธนาคาร จึงต้องมีการยืนยันตัวตนและส่งมอบสิทธิ์การเข้าถึงเสียก่อน โดย Authorization Server จะช่วยเป็นตัวกลางในการจัดการและทำการออก Access Token เพื่อเป็นกุญแจในการเข้าถึง API ต่างๆ ให้กับแอปพลิเคชันภายนอก

OAuth 2.0 สำหรับ KBank API

ด้วยลักษณะของ Services ที่ทางธนาคารเปิดให้เชื่อมต่อในปัจจุบัน หลายๆ API Product จะเน้นไปที่การให้บริการกับพารท์เนอร์หรือบริษัทต่างๆ เช่น บริการสร้าง QR Payment, Slip Verification ดังนั้นรูปแบบการเชื่อมต่อและการยืนยันตัวตน รวมถึงสิทธิ์การเข้าถึงจะเป็นลักษณะ Business to Business หรือ Host to Host ซึ่ง “Client Credentials” เป็น Flow ที่สามารถตอบโจทย์เรื่องนี้ได้เป็นอย่างดี

เพื่อให้ได้เนื้อหาที่สั้นและกระชับ เหมาะสำหรับผู้สนใจที่จะมาเชื่อมต่อ API กับทางธนาคาร ผมขอเจาะไปที่ “Client Credentials” ซึ่งเป็น Grant Type ที่ KBank ใช้เป็นหลักกันเลยนะครับ ส่วนรายละเอียดข้อมูลของ Grant Type ประเภทอื่น จะมีกล่าวถึงในภาคผนวกท้ายบทความอีกทีครับ

OAuth 2.0 — Client Credentials ทำงานอย่างไร

Photo from https://www.authlete.com/resources/videos/oauth2-flows/

ลำดับการทำงานของ OAuth 2.0 Client Credentials จะเป็นดังนี้ครับ

  1. Partner App ที่ต้องการเชื่อมต่อ API ต้องเริ่มยืนยันตัวตนก่อน โดยต้องทำการเรียก OAuth Request Token เข้ามาที่ Authorization Server Endpoint พร้อมระบุ Client ID และ Client Secret เข้ามาด้วย
  2. หากการยืนยันผ่าน ตัว Authorization Server จะสร้าง Access Token ส่งกลับไปให้
  3. แอปสามารถเรียกใช้ API ที่ลงทะเบียนไว้กับทางธนาคาร เช่น QR Payment API โดยในทุกๆ การเรียกใช้จะต้องส่ง Access Token เข้ามาด้วย หากธนาคารทำการ Verify Access Token ที่ส่งเข้ามาและพบว่าถูกต้อง พาร์ทเนอร์มีสิทธิ์ในการเข้าถึง API ดังกล่าวจริง ระบบจะทำการประมวลผล API เหล่านั้นต่อไปให้ครับ

ดังนั้นจะเห็นว่าหากต้องการเชื่อมต่อ API สิ่งแรกที่ต้องมีเลยคือ Client ID และ Client Secret ที่ทางธนาคารออกไว้ให้ ซึ่งภายใต้ Client ID จะมีการกำหนดสิทธิ์ตามที่ลงทะเบียนไว้เรียบร้อยว่า Partner App มีสิทธิ์ในการเข้าถึง API Service ไหนได้บ้าง รวมทั้งสามารถเรียกใช้ได้ในปริมาณเท่าไหร่อีกด้วย ด้วยจุดนี้ทำให้ธนาคารสามารถควบคุมการเข้าถึง API รวมถึง Resource ต่างๆ ของธนาคารได้ครับ

เริ่มสร้าง OAuth 2.0 Request Token

เราสามารถนำ Client ID และ Client Secret มาสร้าง Request Message ได้เลย โดยนำมาจัดทำในรูปแบบ Basic Authentication ตามมาตรฐาน แต่หากจำเป็นต้องสร้างเองแบบ Manual ผมขอแนะนำขั้นตอนตามด้านล่างนี้ครับ

ตัวอย่าง หากเรามี Client ID และ Client Secret ดังนี้

Consumer ID = a2FzaWtvcm5iYW5rdXNlcg==
Consumer Secret = a2FzaWtvcm5iYW5rcGFzc3dvcmQ=

  1. จัดฟอร์แมตข้อมูลในรูปแบบ <Consumer ID>:<Consumer Secret> ดังนี้ a2FzaWtvcm5iYW5rdXNlcg==:a2FzaWtvcm5iYW5rcGFzc3dvcmQ=
  2. นำชุดข้อมูลมาเข้ารหัสในรูปแบบ Base64 Encoder ได้ดังนี้ YTJGemFXdHZjbTVpWVc1cmRYTmxjZz09OmEyRnphV3R2Y201aVlXNXJjR0Z6YzNkdmNtUT0=
  3. นำชุดข้อมูลที่ผ่านการเข้ารหัสแล้ว ไปจัดวางในส่วน Header ตามฟอร์แมตดังนี้ Authorization: Basic <ชุดข้อมูลที่ผ่านการเข้ารหัส> ซึ่งก็คือ Authorization: Basic YTJGemFXdHZjbTVpWVc1cmRYTmxjZz09OmEyRnphV3R2Y201aVlXNXJjR0Z6YzNkdmNtUT0=

หลังจากนั้นระบุใน Header เป็น Content-Type: application/x-www-form-urlencoded และระบุใน Body เป็นคำว่า grant_type=client_credentials จากนั้นเรียกไปที่ Authorization Endpoint ที่ทางธนาคารจัดเตรียมไว้ให้ได้เลยครับ

ขอย้ำหนักๆ เลยนะครับว่า Request Token Message นี้ไม่ใช่ application/json และเราไม่ต้องการอักษรปีกกาเปิดปิดในเนื้อ Body นะครับ

ตัวอย่าง Request Message ในมุมมองของ Postman

กำหนด Authorization บน Postman
กำหนด Body เป็น x-www-form-urlencoded และใส่ grant_type

ตัวอย่าง Request Message ในมุมมองของ cURL

curl -v --key kbank.test.2.key \
--cert kbank.test.2.crt \
--location --request POST 'https://openapi-sandbox.kasikornbank.com/oauth/token' \
--header 'Authorization: Basic YTJGemFXdHZjbTVpWVc1cmRYTmxjZz09OmEyRnphV3R2Y201aVlXNXJjR0Z6YzNkdmNtUT0=' \
-- header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials'

ตัวอย่าง Response Message

ดังตัวอย่างนี้จะเห็นได้ว่า Authorization Server ทำการตอบ Access Token กลับมาให้ ทางแอปสามารถนำค่านี้ไปใช้ในการเรียก API ที่ต้องการต่อไปได้เลยครับ โดย Field ‘expired_in’ จะบอกอายุ Token ในหน่วยวินาที ในที่นี้จะเห็นว่า Token จะมีอายุประมาณ 30 นาทีก่อนที่จะหมดอายุ โดยหาก Token หมดอายุก็สามารถทำการเรียก Request Token เข้ามาใหม่เพื่อขอ Token ใหม่ได้เรื่อยๆ ครับ

ทางธนาคารขอความร่วมมือ Partner App ให้ทำการ Reuse Access Token ตามเวลาที่กำหนด 30 นาที ก่อนจะทำการเรียกเข้ามาใหม่ด้วยนะครับ เพื่อ Performance ที่ดีของทั้งฝั่ง Client และ Server

นำ Access Token ไปใช้ต่ออย่างไร

Partner App สามารถนำ Access Token ที่ได้มาไปเรียก API ต่อได้ง่ายๆ โดยกำหนดเป็น Bearer Token ในส่วน Header ของ API ที่ต้องการเรียกใช้งาน เพียงเท่านี้ก็สามารถเรียก API ได้แล้วครับ

แต่หากต้องการทำ Bearer Token แบบ Manual เอง ก็สามารถทำได้โดยนำไปจัดวางในส่วน Header ตามฟอร์แมตดังนี้ Authorization: Bearer <access token>

ตัวอย่าง การใส่ Token ไปใน Request Message ในมุมมองของ Postman

ตัวอย่าง การใส่ Token ไปใน Request Message ในมุมมองของ cURL

curl --location --request POST 'https://openapi-sandbox.kasikornbank.com/oauth/token' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer a2FzaWtvcm5iYW5rdG9rZW4=' \
--data-raw '{…}'

สรุปครับ

ด้วยขั้นตอนทั้งหมดข้างต้น Partner App ที่ได้รับการรับรองจากธนาคารก็จะสามารถเรียกใช้งาน API ที่ทำการลงทะเบียนไว้ได้แล้วครับ

สุดท้ายนี้…บทความใน EP.2 กล่าวถึงพื้นฐานและความเข้าใจในการยืนยันตัวตนผ่าน OAuth 2.0 Client Credentials รวมถึงสอนการสร้าง Request Message พร้อมตัวอย่าง และนำเสนอแนวทางในการปฏิบัติจริง เพื่อเป็นแนวทางสำหรับผู้สนใจเข้ามาศึกษาหรือต้องการเข้ามาเชื่อมต่อ API กับ KBank ทางผู้เขียนหวังเป็นอย่างยิ่งว่าบทความนี้จะมีประโยชน์ไม่มากก็น้อยสำหรับผู้อ่านทุกคนนะครับ หากเนื้อหาส่วนไหนผิดพลาดประการใดต้องขออภัยมา ณ ที่นี้ด้วยครับ

สำหรับผู้ที่สนใจจะเข้ามาเชื่อมต่อกับ KBank หรือสนใจศึกษาเกี่ยวกับ API สามารถเข้าไปได้ที่ URL นี้ครับ https://apiportal.kasikornbank.com/

ภาคผนวก: OAuth 2.0 Grant Types

OAuth 2.0 มีการกำหนด Flow ไว้หลายรูปแบบในการให้ Client App ทำการร้องขอ Access Token เพื่อเข้าถึง Resource ต่างๆ โดยจะมีอยู่ 4 รูปแบบ “Grant Types” ที่เป็นที่นิยม แต่ละ Grant Type จะมี Use Case และข้อดีข้อเสียที่แตกต่างกัน จึงต้องลองพิจารณาว่ารูปแบบไหนมีความเหมาะสมกับ Business Case ของเรามากที่สุด

  1. Authorization Code หรือในอีกชื่อหนึ่งคือ Three-Legged OAuth จัดเป็นรูปแบบที่มีความปลอดภัย (Secure) มากที่สุด ซึ่งก่อนที่ Authorization Server จะออก Access Token ให้กับแอปในการใช้เข้าถึง Resource ทาง End User ต้องทำการยืนยันตัวตนและมอบความยินยอมโดยตรงกับฝั่ง Resource Server ให้เรียบร้อยเสียก่อน รูปแบบนี้มักจะเจอเวลาที่ User กำลังใช้แอปอยู่แล้วมีการสลับหน้าจอบราวเซอร์ไปสู่หน้าล็อกอินของ Resource Server อื่นเพื่อให้ยืนยันตัวตน ซึ่งจะเจอบ่อยตอนใช้เฟสบุ๊กหรือทวิตเตอร์ หลังจากยืนยันตัวตนสำเร็จ แอปจะได้รับ Authorization Code เพื่อใช้ในการแลกเปลี่ยนเป็น Access Token ต่อไปอีกที ข้อดีของวิธีนี้คือ Client App จะไม่มีทางทราบ Username และ Password ที่ End User ใช้กับ Resource Server จึงมีความปลอดภัยสูง
  2. Implicit เปรียบเสมือน Authorization Code Grant Type แบบย่อส่วน โดยเมื่อ End User ยืนยันตัวตนกับ Resource Server ผ่านแล้ว ทาง Authorization Server จะคืน Access Token มาให้แอปโดยตรงทันที (ข้ามเรื่อง Authorization Code ไป) Use Case นี้มักใช้กับแอปฝั่ง Client จำพวกบราวเซอร์ที่ใช้ JavaScript หรือภาษา Script ต่างๆ
  3. Password Credentials รูปแบบนี้ Client App เพียงส่ง Username และ Password ของ End User ให้กับ Authorization Server ระบบจะทำการออก Access Token ให้ทันที สำหรับ Flow นี้แนะนำให้ใช้กับแอปที่มีความน่าเชื่อถือสูงเท่านั้น เพราะแอปสามารถทราบและมองเห็น Username และ Password ของ End User ได้
  4. Client Credentials เหมาะกับการเชื่อมต่อแบบ Host to Host ซึ่ง Client App เชื่อมต่อในนามของตนเองและไม่มีการให้ Resource Owner มายืนยันตัวตนกับระบบปลายทางแต่อย่างใด ภายใต้ Grant Type นี้ แอปสามารถร้องขอ Access Token ผ่านการยืนยัน Client ID และ Client Secret ให้กับ Authorization Server ได้โดยตรง

สำหรับชาวเทคคนไหนที่สนใจเรื่องราวดีๆแบบนี้ หรืออยากเรียนรู้เกี่ยวกับ Product ใหม่ๆ ของ KBTG สามารถติดตามรายละเอียดกันได้ที่เว็บไซต์ www.kbtg.tech

--

--