ปกป้อง API ด้วย AWS Cognito OAuth2 scopes (Part 1)

sc phai Jr.
3 min readJan 25, 2021

เอาละครับวันนี้ก็ได้ฤกษ์เขียน blog โดยวันนี้จะมาพูดเรื่องการทำ Oauth2 บน AWS ก่อนอื่นนั้น ขอแนะนำสิ่งที่ควรรู้ก่อน ไปกันเลย

OAuth2

“OAuth2 คือมาตรฐานหนึ่งของระบบยืนยันตัวตน และจัดการสิทธิ์การเข้าใช้งานระบบต่าง ๆ” ประกอบไปด้วย

  1. Client ชาวบ้านที่จะมาเรียก API เรา
  2. Resource server คือ Server ที่ API เราอยู่
  3. Authorization server คือ Server ที่จะใช้ตรวจสอบสิทธ์ของ Client ก่อนที่จะไปถึง Resource server จริงๆ
  4. Resource owner เจ้าของข้อมูล ที่จะเป็นคนกำหนดว่า Client ไหน เข้าถึง API อะไรได้บ้าง

เนื่องจากใน blog นี้เราจะเน้นไปที่การใช้ Cognito ผมขอกล่าวแค่นี้พอ เยอะกว่านี้ไปหาอ่านเองนะครับ ถถถถ

AWS Cognito

AWS Cognito เป็น Service ของ AWS โดยมีหน้าที่จัดการ Authen User ของ AWS เหมือนกับ Firebase นั้นแล ซึ่งในกรณีนี้เราจะใช้ตัว Cognito เป็น Authorization Server นั้นเอง

AWS API gateway

เป็นตัว Service ของ AWS cloud ที่ทำหน้าที่เป็น gateway ที่เราเปิดให้ชาวบ้านเรียกเข้ามาใช้ API เรา โดยตัว API gateway มันมีความสามารถที่ให้เราสามารถเพิ่มความปลอดภัยให้ API เราได้ ซึ่งหนึ่งในนั้นก็คือ การทำ OAuth2

มาถึงตรงนี้เราก็ได้แนะนำตัวละครที่จะมีส่วนเกี่ยวข้องกับเรื่องนี้ไปแล้ว จากนั้นเรามาดู diagram กันดีกว่า ว่ามันเป็นจั่งได๋ซิ

จากรูปก็คืออธิบายได้ว่า

เมื่อชาวบ้าน (Client)ต้องการจะเรียก API ของเรา สิ่งที่เกิดขึ้นคือ

  1. Client ก็จะเรียกมาที่ Endpoint /oauth2/token โดยส่งข้อมูลเพื่อยืนยันตัวตันตาม grant type ที่เรากำหนด เช่น grant type “Client Credentials” Client ก็จะส่งข้อมูล Client id และ Client Secret มา (grant type นั้นมีหลากหลาย แล้วแต่ Use case ของระบบเรา ไปลองอ่านกันดู)
  2. Authorization server ทำการตรวจสอบข้อมูลที่มาจาก Client ถ้าถุกต้องก็จะทำการ Return access token กลับไป
  3. เมื่อ Client ได้รับ access token แล้ว ก็จะนำไปแปะไว้ใน Header ของ request ที่จะเรียกไปหา endpoint ของ API gateway
  4. API gateway ทำการตรวจสอบ access token ว่า valid หรือเปล่า (จริงๆคนที่ตรวจสอบคือ Authorization server แหละ แต่มันถูกเรียกอีกทีโดย API gateway ) ถ้าถูกต้องก็จะส่งต่อไปที่ Resource server ที่ mapping ไว้ เพื่อทำ business process ต่างๆต่อไป หรือถ้า Token มัน invalid ก็จะ Return error กลับไปหา Client

สังเกตุได้ว่า ชาวบ้านจะต้องมีข้อมูล Client id และ Client Secret ซึ่ง Resource owner เป็นคน Provide ให้ ซึ่งก็คือ pre process ของการทำ Oauth2 แบบ Client Credentials

โอเค เราเกริ่นกันมาเยอะแล้ว มาเริ่มทำจริงกันเลยดีกว่า (ไป ไป ไป้ ป๊ายยย)

สร้าง AWS Cognito user pool และ setup a OAuth application

  • Login ไปที่ AWS Management console จากนั้นก็เปิดไปที่ Service Cognito service
  • เลือก “Manage your user pools” จากนั้นเลือก “Create a user pool”
  • ใส่ชื่อ pool name จากนั้นเลือก “Review defaults” แล้วก็กด “Create pool” โลดดด
  • เมื่อกด Create pool แล้ว ให้ไปที่เมนู “General Settings > App clients” แล้วเลือก “Add an app client” เพื่อเพิ่มข้อมูลของ client ที่จะมาเรียกระบบของเรา
  • ใส่ชื่อ “App client name” แล้วเลือก “Generate client secret” จากนั้นกด “Create app client” ระบบจำทำการสร้าง Client id และ client secrete ให้
  • ไปที่เมนู “Domain name” แล้วก็ใส่ชื่อ domain name เข้าไป โดยสามารถตรวจสอบชื่อ “Domain name” ได้โดยการกด “Check availability” ถ้าใช้ได้ก็ทำการ “Save changes” โลดดด
  • ไปที่ “Resource Servers” แล้วเลือก“Add a resource server” เพิ่มข้อมูลของ Resource server เข้าไป โดยตรงนี้จะมีการเพิ่ม Scope ด้วย เพื่อใช้ในการตรวจสอบสิทธิ์
  • ไปที่ “App client settings” เลือก “Cognito User pool” แล้วเลือก Oauth flow เป็น “Client credentials” แล้วเลือก Custom scopes ที่เราสร้างไปทั้ง read write delete เข้าไป
  • ถึงตรงนี้แล้วเราก็จะได้ Authorization server มาทดสอบกันหน่อย

โดยการทดสอบผมจะใช้ Postman เพื่อความง่ายและสะดวก ทำการ New request มาซักตัว แล้ว เปิดไปที่ tab “Authorization” เลือกดังนี้

Grant type: Client Credentials

Access token URL: https://<your domain name>.auth.ap-southeast-1.amazoncognito.com/oauth2/token

Client ID : ดูได้ในเมนู “App clients”

Client secret : ดูได้ในเมนู “App clients”

ถ้าไม่มีอะไรผิดพลาด เมื่อกด Get new access token ก็จะได้ token หน้าตาแบบนี้

ลองเอา token ที่ได้ ไปแปะดูใน JWT.io ก็จะได้รายละเอียดต่างๆของ access token ประมาณนี้ครับ

อื้ม แก๋ว…

มาถึงตรงนี้ก็ขออนุญาต พอไวสาก่อน โดยใน Part ต่อไป เราจะมาลองสร้าง API ง่ายๆมาซักตัวแล้วทำการผูกเข้ากับ API gateway แล้วก็เพิ่ม Authorization server ที่เราได้สร้างเข้าไปอีกที รอติดตามชมกันได้ครับ

สวัสดี

--

--