ข้ามไปที่เนื้อหาหลัก

OAuth คืออะไร

 OAuth (Open Authentication) คือมาตรฐานที่ใช้ในการยืนยันตัวตน (Authentication) และการตรวจสอบสิทธิ์ (Authorization) โดยเป็นการให้เจ้าของข้อมูล (user) ยินยอมให้แอพพลิเคชั่นเข้าถึงข้อมูลได้ เช่น การล็อกอินด้วย Facebook ใน JOOX โดย JOOX จะร้องขอข้อมูลส่วนตัวของ user เพื่อใช้สำหรับเข้าสู่ระบบ เป็นต้น โดยปัจจุบันเป็น version 2 หรือ OAuth 2.0



ประเภทการให้สิทธิ์ (Grant type)

Grant type ของ OAuth 2.0 จะมีทั้งหมด 4 ประเภท ได้แก่

1. Authorization Code

เป็น Grant type ที่ได้รับความนิยมที่สุดในปัจจุบัน เนื่องจากมีการนำไปใช้โดย Facebook และ Google โดยจะใช้สำหรับให้ user ซึ่งเป็นเจ้าของข้อมูล ให้สิทธิ์แอพพลิเคชั่นในการเข้าถึงข้อมูลของตัวเองได้ โดยจะเป็นการกรอก username และ password เพื่อล็อกอินและให้สิทธิ์ที่ Authorization server เพื่อส่ง Code กลับมา แล้วให้แอพพลิเคชั่นไปขอ access token อีกที

2. Implicit

จะมีความคล้ายกับแบบ Authorization Code แต่ต่างกันที่ทางแอพพลิเคชั่นไม่ต้องทำหน้ารับ Code แล้วไปขอ access token อีกที แต่จะได้ access token กลับมาเลยผ่านทาง query string และไม่ต้องใช้ client secret เพื่อยืนยันตัวตนของแอพพลิเคชั่น

3. Password

เป็นการขอสิทธิ์โดย user จะให้ username และ password กับทางแอพพลิเคชั่นโดยตรง เพื่อนำไปขอ access token

4. Client Credentials

เป็นการขอสิทธิ์โดยแอพพลิเคชั่นจะใช้ client id และ client secret ในการส่งไปขอ access token ที่ Authorization server โดยจะเป็นการขอระหว่าง machine to machine

รูปแบบการเลือกใช้ Grant type — https://alexbilbie.com/images/oauth-grants.svg

การทำงานของแต่ละ Grant type

ในการทำงานของ OAuth จะมีตัวละครทั้งหมด 3 ตัวนะครับ คือ

  • User หรือ Resource Owner ซึ่งก็คือ User ที่เป็นเจ้าของข้อมูลนั่นเอง
  • Resource Server หรือ Authorization Server ซึ่งก็คือ API Gateway นั่นเอง
  • Application (Client)
Flow การทำงานของ OAuth — https://assets.digitalocean.com/articles/oauth/abstract_flow.png

1. Authorization Code Flow

ขั้นตอนที่ 1 ทาง Application จะต้องวิ่งไปที่ Authorization endpoint โดยจะต้องส่ง parameter ดังนี้

  • response_type = code
  • client_id คือ client id ที่ทางแอพพลิเคชั่นได้ลงทะเบียนขอเอาไว้
  • redirect_uri คือ callback ที่ทางแอพพลิเคชั่นจะนำไปใช้ขอ access token อีกที โดยจะเป็น callback ที่ได้ลงทะเบียนขอเอาไว้
  • scope คือ scope ของข้อมูลที่ทางแอพพลิเคชั่นต้องการ
  • state(optional) คือ CSRF Token เพื่อเอาไว้ให้ทางแอพพลิเคชั่นนำไป validate session ของ user

จากนั้น Authorization server จะขึ้นหน้า login เพื่อให้ user ยืนยันตัวตน และให้ user ยืนยันสิทธิ์เพื่อให้ทางแอพพลิเคชั่นนำ code ไปขอ access token ต่อ โดยจะมาในรูปแบบ callback กลับไปแล้วส่ง code และ state กลับไปเป็น query string

ส่วนขั้นตอนต่อมา เมื่อได้ code มาแล้ว ทางแอพพลิเคชั่นจะต้องวิ่งไป Token endpoint เพื่อขอ Token โดยส่ง parameter ดังนี้

  • grant_type = authorization_code
  • client_id คือ client id ที่ทางแอพพลิเคชั่นได้ลงทะเบียนขอเอาไว้
  • client_secret คือ client secret ที่ทางแอพพลิเคชั่นได้ลงทะเบียนขอเอาไว้
  • redirect_uri
  • code ที่ทาง Authorization server ส่งกลับมา

และทาง Authorization server จะส่ง access token กลับมาในรูปแบบ JSON โดยจะประกอบไปด้วย

  • token_type
  • expires_in
  • access_token
  • refresh_token
https://assets.digitalocean.com/articles/oauth/auth_code_flow.png

2. Implicit Flow

ขั้นตอนจะคล้ายๆกับแบบ Authorization Code คือส่ง parameter ดังนี้ครับ

  • grant_type = token (ต่างกันแค่นี้)
  • client_id คือ client id ที่ทางแอพพลิเคชั่นได้ลงทะเบียนขอเอาไว้
  • redirect_uri คือ callback ที่ทางแอพพลิเคชั่นจะนำไปใช้ขอ access token อีกที โดยจะเป็น callback ที่ได้ลงทะเบียนขอเอาไว้
  • scope คือ scope ของข้อมูลที่ทางแอพพลิเคชั่นต้องการ
  • state(optional) คือ CSRF Token เพื่อเอาไว้ให้ทางแอพพลิเคชั่นนำไป validate session ของ user

แต่ต่างกันตรงที่แบบ Implicit จะได้ access token กลับมาเป็น query string โดยจะประกอบไปด้วย

  • token_type
  • expires_in
  • access_token
  • state(optional) ถ้าส่งไป จะส่งกลับมาเพื่อให้ทางแอพพลิเคชั่นใช้ในการ validate session
https://assets.digitalocean.com/articles/oauth/implicit_flow.png

3. Password Flow

สำหรับ grant type ที่เป็น password นี้แอพพลิเคชั่นอาจจะทำหน้า login ขึ้นมาเอง และ POST ส่ง username และ password ไปพร้อมกันครั้งเดียวเลย โดยใช้ parameter ดังนี้

  • grant_type = password
  • client_id คือ client id ที่ทางแอพพลิเคชั่นได้ลงทะเบียนขอเอาไว้
  • client_secret คือ client secret ที่ทางแอพพลิเคชั่นได้ลงทะเบียนขอเอาไว้
  • scope คือ scope ของข้อมูลที่ทางแอพพลิเคชั่นต้องการ
  • username
  • password

และทาง Authorization server จะส่ง response กลับมาเป็น JSON โดยประกอบด้วย

  • token_type
  • expires_in
  • access_token
  • refresh_token

4. Client Credentials Flow

สำหรับ grant type นี้ จะไม่ต้องใช้ username และ password ของ user ทางแอพพลิเคชั่นก็สามารถส่งไปขอ access token โดยใช้แค่ client id และ client secret ได้เลย โดยใช้ parameter ดังนี้

  • grant_type = client_credentials
  • client_id คือ client id ที่ทางแอพพลิเคชั่นได้ลงทะเบียนขอเอาไว้
  • client_secret คือ client secret ที่ทางแอพพลิเคชั่นได้ลงทะเบียนขอเอาไว้
  • scope คือ scope ของข้อมูลที่ทางแอพพลิเคชั่นต้องการ

และทาง Authorization server จะส่ง response กลับมาเป็น JSON โดยประกอบด้วย

  • token_type
  • expires_in
  • access_token

ที่มา https://medium.com/@panuwat.w/oauth-%E0%B8%84%E0%B8%B7%E0%B8%AD%E0%B8%AD%E0%B8%B0%E0%B9%84%E0%B8%A3-bde9e1f773f9

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

การเพิ่ม Font ภาษาไทยอื่นๆ เข้าไปใช้งานใน MPDF

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

การใช้งาน คำสั่ง file_exists() อย่างเข้าใจ

นี่อาจจะไม่เรื่องใหม่อะไรสำหรับ Professional ทั้งหลาย แต่ว่าสำหรับผมที่เข้าใจ และใช้งานอย่างผิดๆ มาตลอด จนบางทีก็เข้าใจว่า เราเขียนผิด หรือ คำสั่งมันใช้งานไม่ได้ วันนี้จะขอมาพูดถึงเรื่องของคำสั่ง PHP ที่ชื่อ file_exists เป็นคำสั่งที่ใช้สำหรับตรวจสอบไฟล์ว่ามีอยู่จริงหรือไม่? ตัวอย่างการใช้งานแบบผิดๆ ที่ผมใช้ก็คือ file_exists('/images/news/helloworld.jpg'); ผลลัพธ์ที่ได้คือ FALSE ถึงแม้ว้าจะมีไฟล์นั้นอยู่จริงก็ตาม ซึ่งในความเป็นจริงแล้ว การใช้งานที่ถูกต้องคือ file_exists($_SERVER['DOCUMENT_ROOT'] . '/images/news/helloworld.jpg'); จากตัวอย่างที่ถูกต้อง ทำให้เข้าใจแบบง่ายๆ ว่าคำสั่ง file_exists นั้นใช้สำหรับเช็ค path ในโฟลเดอร์จริงๆ เท่านั้น ไม่สามารถเช็คจาก URL ได้ อันนี้เป็นเรื่องง่ายๆ ที่ผมเข้าใจผิดมาอยู่นานเลยทีเดียวเลยต้องขอลงบันทึกเตือนตัวเองไว้อีกที :3

มาเข้าใจ และใช้ Datatable ดึงข้อมูลแบบ Server-side ด้วย PHP, MySQL กันเถอะ

มีช่วงหนึงผมเคยนำ datatable มาพัฒนาในงานแต่เกิดปัญหาเนื่องจากมีข้อมูลขนาดใหญ่ ทำให้เกิดการโหลดในครั้งแรกที่โหลดหน้าเพจนั้นๆ เนื่องจากผมใช้ Ajax ในการโหลดข้อมูลทั้งหมดมาในครั้งเดียวด้วยจำนวนข้อมูล 1000 ขึ้น ซึ่งตอนนั้นผมคิดว่าการทำ preload น่าจะช่วยได้ แต่ว่าถ้า user เกิดเผลอไปกด refesh หรือแก้ไขข้อมูลเวลากลับมาที่หน้าข้อมูลก็ต้องโหลดใหม่อีก ทำให้ผมเลิกใช้ datatable ไปเลย เพราะคิดว่ามันคงไม่เหมาะ แต่ในความจริงแล้ว datatable ก็ได้มีสิ่งที่มาแก้ในจุดนั้นได้ ซึ่งเรียกว่า server-side โดยการที่อนุญาตให้เรา query ข้อมูลออกมาก่อนแล้วส่งมาให้ datatable อ่านข้อมูลในจำนวนที่น้อยลง หลักการก็เหมือนๆ กับบทความการทำสร้าง XML จากข้อมูลขนาดใหญ่นั่นแหละครับ แต่มีเงื่อนไขเพียงแต่ว่า ต้อง Filter และส่งข้อมูลออกมาในรูปแบบที่ตรงตามหลักของ datatable เท่านั้น ( บางครั้งเวลาเข้าไปอ่าน Document หรือดู Example จะงงๆ ว่าอะไรเยอะแยะ ) โดยวันนี้จะมาแนะนำการใช้งานแบบง่ายๆ กันเลย :D