ทำไม Developer ต้องรู้จัก OAuth

http://www.daimto.com/wp-content/uploads/2015/08/Google-OAuth@2x.png

ช่วงที่ผมกำลังฝึกงานอยู่ ผมได้รับ Requirement ให้ทำระบบล็อกอิน โดยใช้ Browser-based authentication (OAuth2) ของ Medium Account วันนี้ก็เลยจะมาแนะนำ OAuth(โออท) ให้ทุกคนได้รู้จักกัน

เนื้อหาในบทความนี้จะพูดถึง OAuth2เป็นหลักนะครับ

เนื่องจากทุกวันนี้โลกของ Developer ก็ไปไวสะเหลือเกิน หลายๆท่านก็คงคุ้นเคยกับการเขียนแอปพลิเคชันที่มีระบบล็อกอินด้วย Username และ Password แต่ทุกวันนี้
บางแอปพลิเคชันก็หันมาเพิ่มการ Log in กับ Facebook, Google, Twitter, Email และอื่นๆกันแล้ว

เอ… แล้วเจ้า OAuth มันเกี่ยวกับอะไรละ มารู้จักในหัวข้อต่อไป

OAuth คืออะไร?

OAuth “โอออท” ย่อมาจาก Open Authentication ปัจจุบันเป็น Version 2

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

ทำไม Developer ต้องใช้ OAuth

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

แต่…เรามีทางออกเพียงแค่คุณโทรมาหาเราในไม่กี่วินาทีนี้ 
เดี๋ยวๆพักช่วงโฆษณาแปป…

เจ้า OAuth นี่แหละจะมาช่วยแก้ปัญหาเหล่านี้ เพราะการเขียนระบบ Login โดยใช้ OAuth จะเอาสิ่งที่เรียกว่า Token ไปใช้แทน Username และ Password ในการเข้าสู่ระบบแอปพลิเคชันของเรา ดังนั้นแฮกเกอร์จะไม่สามารถรู้ Username และ Password ของผู้ใช้ในแอปพลิเคชันของเราได้

เอ… แล้วมันทำงานยังไง มาดูบทบาทกัน

บทบาทของ OAuth2

  1. Resource Owner
  2. Resource Server
  3. Client
  4. Authorization Server

Resource Owner
คือ เจ้าของทรัพยากร หรือ ผู้ใช้ที่เป็นเจ้าของข้อมูล เช่น ใน Facebook ข้อความที่เราโพส รูปภาพที่อัปโหลด วิดีโอที่อัปโหลด เพื่อน ข้อมูลติดตาม และอื่นๆ สิ่งเหล่านี้เป็นข้อมูลของเรา เราเป็นเจ้าของข้อมูล

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

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

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

ยกตัวอย่างการทำงาน OAuth ของ Facebook แรกเริ่มผู้ใช้ต้องล็อกอินเข้าสู่ระบบ Facebook ก่อนเพื่อยืนยันว่าผู้ใช้คือใครและยอมรับสิทธิ์ ภายหลังการตรวจสอบสิทธิ์ระบบจะส่ง Token กลับมาให้ เพื่อให้แอปพลิเคชันใช้จัดเก็บและส่งกลับมาหาเซิร์ฟเวอร์อีกครั้งเมื่อเรียกใช้ข้อมูลของผู้ใช้

ตัวอย่างการทำ Log in with Facebook ด้วย OAuth
https://www.makewebeasy.com/blog/2015/10/สมัครสมาชิกด้วยfacebook/

https://assets.digitalocean.com/articles/oauth/abstract_flow.png

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

(2) Authorization Grant (Receives)
เมื่อเจ้าของข้อมูลอนุมัติสิทธิ์แล้ว ระบบจะส่งสิทธิ์การเข้าถึงข้อมูลให้กับแอปพลิเคชันเก็บไว้เพื่อใช้ในการติดต่อข้อมูลกับเซิร์ฟเวอร์ โดยสิทธิ์การเข้าถึงข้อมูลจะสามารถใช้ได้ครั้งเดียว หากต้องการขอสิทธิ์ใหม่ต้องกลับไปทำในขั้นตอนที่1

(3) Authorization Grant (Requests Token)
เมื่อที่แอปพลิเคชันมีสิทธิ์ในการเข้าถึงข้อมูลแล้ว แอปพลิเคชันจะเอาสิทธิ์ไปสร้างคำร้องขอ Token กับเซิร์ฟเวอร์

(4) Access Token
หลังจากที่เซิร์ฟเวอร์ตรวจสอบคำร้องขอ Token ถูกต้องแล้ว เซิร์ฟเวอร์ก็จะส่ง Token มาให้กับแอปพลิเคชัน

(5) Access Token
หลังจากที่แอปพลิเคชันได้รับ Token แล้ว แอปพลิเคชันจะเอา Token ไปสร้างคำร้องขอข้อมูลที่มีการป้องกันกับเซิร์ฟเวอร์ เพื่อให้เซิร์ฟเวอร์ตรวจสอบ Token

(6) Protected Resource
หลังจากที่เซิร์ฟเวอร์ตรวจสอบ Token ถูกต้องแล้ว เซิร์ฟเวอร์ก็จะส่งข้อมูลของผู้ใช้มาให้กับแอปพลิเคชัน

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

ประเภทการให้สิทธิ์ขึ้นอยู่กับการใช้งานของแอปพลิเคชันนั้นๆ มีอยู่ทั้งหมด 4 ประเถทได้แก่
1. Authorization Code
2. Implicit
3. Resource Owner Password Credentials
4. Client Credentials

Grant Type: Authorization Code

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

https://assets.digitalocean.com/articles/oauth/auth_code_flow.png

(1)User Authorization Request
แอปพลิเคชันส่งคำร้องขอการให้สิทธิ์กับผู้ใช้ผ่านเว็บบราวเซอร์ และเว็บบราวเซอร์จะส่งคำขอให้เซิร์ฟเวอร์ตรวจสอบ

https://example.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

(2)User Authorization Application
หลังจากที่เจ้าของข้อมูลได้รับคำขอสิทธิ์แล้ว เจ้าของข้อมูลต้องอนุมัติสิทธิ์การเข้าถึงข้อมูลให้แอปพลิเคชันผ่านเว็บบราวเซอร์ และส่งสิทธิ์ให้เซิร์ฟเวอร์ตรวจสอบ

https://assets.digitalocean.com/articles/oauth/authcode.png

(3) Authorization Code Grant
หลังจากที่เซิร์ฟเวอร์ตรวจสอบสิทธิ์สำเร็จแล้ว เซิร์ฟเวอร์ก็จะส่งโค้ดการให้สิทธิ์ให้กับแอปพลิเคชัน

https://example.com/callback?code=AUTHORIZATION_CODE

(4) Access Token Request
หลังจากที่แอปพลิเคชันได้รับโค้ดการให้สิทธิ์แล้ว แอปพลิเคชันจะส่งคำขอ Token ให้กับเซิร์ฟเวอร์ตรวจสอบ

https://example.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

(5) Access Token Grant
หลังจากที่เซิร์ฟเวอร์ตรวจสอบคำขอ Token แล้ว แอปพลิเคชันจะได้รับ Token จากเซิร์ฟเวอร์

{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101,
"info":{"name":"Mark E. Mark",
"email":"example@oauth.com"
}
}

Grant Type: Implicit

ประเภทการให้สิทธิ์แบบ Implicit ใช้สำหรับ mobile apps และ web applications
ซึ่งไม่รับประกันความปลอดภัยข้อมูลของผู้ใช้ Token จะถูกส่งไปยังผู้ใช้เพื่อส่งต่อไปยังแอปพลิเคชัน ดังนั้นอาจมีการเปิดเผย Token ต่อผู้ใช้และแอปพลิเคชันอื่นๆบนอุปกรณ์ของผู้ใช้

https://example.com/v1/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
https://assets.digitalocean.com/articles/oauth/implicit_flow.png

(1)User Authorization Request
แอปพลิเคชันส่งคำร้องขอการให้สิทธิ์กับผู้ใช้ผ่านเว็บบราวเซอร์ และเว็บบราวเซอร์จะส่งคำขอสิทธิ์ให้เซิร์ฟเวอร์ตรวจสอบ

(2)User Authorization Application
หลังจากที่เจ้าของข้อมูลได้รับคำขอสิทธิ์แล้ว เจ้าของข้อมูลต้องอนุมัติสิทธิ์การเข้าถึงข้อมูลให้แอปพลิเคชันผ่านเว็บบราวเซอร์ แล้วส่งสิทธิ์ให้เซิร์ฟเวอร์ตรวจสอบ

(3)Redirect URI with Access Token
หลังจากที่เซิร์ฟเวอร์ตรวจสอบสิทธิ์สำเร็จแล้ว เซิร์ฟเวอร์ก็จะส่ง Token และ redirect กลับไปที่เว็บบราวเซอร์

(4)Follow Redirect URI (Retain Token)
หลังจากที่เว็บบราวเซอร์ได้รับ Token แล้ว เว็บบราวเซอร์จะส่ง Token และ redirect กลับไปที่แอปพลิเคชันให้เก็บ Token ไว้

(5)Send Token Extract Script
หลังจากที่แอปพลิเคชันเก็บ Token ไว้แล้ว แอปพลิเคชันจะส่ง Token ต้นฉบับ การเข้าถึง Token ให้กับเว็บบราวเซอร์

(6)Pass Token to Application
หลังจากที่บราวเซอร์ได้รับ Token ต้นฉบับแล้ว บราวเซอร์จะส่ง Token กลับไปที่แอปพลิเคชัน

Grant Type: Resource Owner Password Credentials

ประเภทการให้สิทธิ์แบบ Resource Owner Password Credentials เป็นการรับรองด้วยการให้สิทธิ์รหัสผ่านของเจ้าของข้อมูล โดยเจ้าของข้อมูลจะให้ข้อมูลการรับรอง (Username และ Password) โดยตรงกับแอปพลิเคชัน ซึ่งใช้ข้อมูลประจำตัวเพื่อขอรับ Token การเข้าถึงข้อมูล

https://oauth.example.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID

Password Credentials Flow

https://www.ibm.com/developerworks/library/se-oauthjavapt1/image001.png

(A)Resource owner Password credentials
เจ้าของข้อมูลส่ง Username และ Password ให้กับแอปพลิเคชัน

(B)Resource owner Password credentials
หลังจากที่แอปพลิเคชันได้ Username และ Passwordแล้ว แอปพลิเคชันจะส่ง Username และ Password ไปให้กับเซิร์ฟเวอร์ตรวจสอบ

©Access token with optional refresh token
หลังจากที่เซิร์ฟเวอร์ตรวจสอบ Username และ Password สำเร็จแล้ว เซิร์ฟเวอร์จะส่ง Token ให้กับแอปพลิเคชัน และรีเฟรช Token

Grant Type: Client Credentials

ประเภทการให้สิทธิ์แบบ Client Credentials โดยแอปพลิเคชันการส่งรหัสข้อมูลประจำตัว(client ID, client secret)เพื่อร้องขอ Token กับเซิร์ฟเวอร์

https://oauth.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET
https://www.ibm.com/developerworks/library/se-oauthjavapt2/image001.png

(A)Client credentials
แอปพลิเคชันส่งรหัสข้อมูลประจำตัวให้เซิร์ฟเวอร์ตรวจสอบ

(B)Access token
หลังจากที่เซิร์ฟเวอร์ตรวจสอบรหัสข้อมูลประจำตัวสำเร็จแล้ว เซิร์ฟเวอร์จะส่ง Token มาให้กลับแอปพลิเคชัน


สรุป

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


เอกสารอ้างอิง

Internet Engineering Task Force (IETF)(2012). The OAuth 2.0 Authorization Framework. Retrieved November, 27, 2017,from
https://tools.ietf.org/html/rfc6749

Mitchell Anicas (2014). An Introduction to OAuth 2. Retrieved November, 27, 2017,from
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2