OAuth2 là gì?

OAuth2 không đơn thuần chỉ là giao thức kết nối, nó là một "nền tảng" mà chúng ta phải triển khai ở cả hai phía: Client và Server. Sau đây hãy cùng làm quen với các tác nhân (hay đối tượng) tham gia vào hoạt động của OAuth2.

Các tác nhân (đối tượng) trong Oauth2
OAuth2 làm việc với 4 đối tượng mang những vai trò riêng:

Resource Owner (User): Là những người dùng ủy quyền cho ứng dụng cho phép truy cập tài khoản của họ. Sau đó ứng dụng được phép truy cập vào những dữ liệu người dùng nhưng bị giới hạn bởi những phạm vi (scope) được cấp phép. (VD: chỉ đọc hay được quyền ghi dữ liệu) => Resource Owner chính là bạn.

Client (Application): Là những ứng dụng mong muốn truy cập vào dữ liệu người dùng. Trước khi được phép tương tác với dữ liệu thì ứng dụng này phải qua bước ủy quyền của User, và phải được kiểm tra xác nhận thông qua API. => Có thể hiểu là các ứng dụng sử dụng Facebook, Twitter, Google API chẳng hạn => Client là Facebook.

Resource Server (API): Nơi lưu trữ thông tin tài khoản của User và được bảo mật.

Authorization Server (API): Làm nhiệm vụ kiểm tra thông tin user (VD: ID), sau đó cấp quyền truy cập cho Application thông qua việc phát sinh "access token".

Resource ServerAuthorization Server chính là điểm khác biệt cơ bản giữa OAuth2OAuth1 khi tách biệt được hai thao tác: chứng thực (Authorization) và cung cấp thông tin người dùng (Resource) thành 2 Server.

Vấn đề về token của OAuth2

https://accounts.google.com/o/oauth2/token

Khi truy suất vào bộ API của Google hay Facebook thì đụng tới cái này, có vài vấn đề cần hỏi các bác:

+ khi lấy được access token và refresh token, sau một thời gian thì access token sẽ hết hạn. vậy để tạo một access token mới từ refresh token thì phải làm sao?
+ việc lưu lại refresh token cần những cơ chế bảo mật như thế nào để ko bị lộ?

Authorization Grant (loại ủy quyền)

Loại ủy quyền phụ thuộc vào phương thức mà Application sử dụng để yêu cầu ủy quyền, Oauth2 định nghĩa ra 4 loại:

  1. Authorization Code: sử dụng với các server-side Application.
  2. Implicit: sử dụng với các Mobile App (ứng dụng chạy trên thiết bị của User) hoặc Web App (có thể hiểu là Browser App cũng được, VD: Chrome Extension).
  3. Resource Owner Password Credentials: sử dụng với các Trusted Application, kiểu như những ứng dụng của chính Service.
  4. Client Credentials: sử dụng với các ứng dụng truy cập thông qua API.

1) Grant Type: Authorization Code

Step 1: Yêu cầu authorization_code

Đầu tiên Application sẽ gửi User link đến nơi để bắt đầu quá trình nhận authorization_code. Ví dụ:

https://OAUTH_SERVER.DOMAIN/OAuth/Authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

https://OAUTH_SERVER.DOMAIN/oauth/authorize: API Authorization Endpoint.

client_id=CLIENT_ID: Client ID của Application sau khi đăng ký với Service.

redirect_uri=CALLBACK_URL: Nơi quay về sau khi sinh ra authorization_code.

response_type=code: tham số để hiểu được ứng dụng đang yêu cầu nhận authorization_code.

scope=read: định nghĩa phạm vi cho phép Application truy cập.

Step 2: User ủy quyền cho Application

Khi User click vào link, việc đầu tiên cần làm là User đăng nhập để định danh người dùng. Sau đó User sẽ được dẫn đến màn hình để Cho phép hoặc Từ chối Application truy cập các thông tin của mình.

Step 3: Application nhận authorization_code

Nếu User click vào Authorize application, bên cung cấp dịch vụ sẽ chuyển hướng người dùng đến Application redirect URI (đã được đăng ký từ trước đó), tại đây Application sẽ phải thực hiện thao tác lưu lại authorization_code. Ví dụ:

https://APPLICATION.DOMAIN/callback?code=AUTHORIZATION_CODE

Step 4: Application yêu cầu access_token

Sau khi nhận được authorization_code, Application cần thực hiện Request lên Oauth Server một lần nữa để lấy được access_token. Việc này phải được Application đảm nhận và User không cần thao tác thêm gì nữa. Link request có định dạng như sau:

https://OAUTH_SERVER.DOMAIN/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

 

Step 5: Application nhận access_token

Nếu quá trình ủy quyền (authorization) thành công, phía API sẽ gửi thông tin trả lời dưới dạng JSON chứa access_token (hoặc có thể kèm theo cả refesh_token) tới Application. Dữ liệu trả về có dạng như sau:

{
        "access_token":"ACCESS_TOKEN",
        "token_type":"bearer",
        "expires_in":2592000,
        "refresh_token":"REFRESH_TOKEN",
        "scope":"read",
        "uid":966996,
        "info":
        {
                "name":"Tungshooter",
                "email":"tungshooter@socool.com"
        }
}

Tới đây Application đã được User ủy quyền truy cập. Application có thể sử dụng access_token để truy cập những tài nguyên của dịch vụ mà User cho phép, ví dụ thông tin email, ảnh avatar, ... cho tới khi access_token hết hạn sử dụng. Nếu phía API hỗ trợ và gửi về thêm cả thông tin refresh_token thì Application có thể sử dụng để đổi lấy access_token mới khi access_token cũ hết hạn.

4) Grant Type: Client Credentials

Loại ủy quyền này phục vụ cho việc truy cập vào chính thông tin tài khoản của Application tại Service. Có thể hiểu nôm na là Application mong muốn thay đổi thông tin description hoặc redirect_uri hay lấy thông tin của chính Application thông qua API. Bạn có thể thấy là loại ủy quyền này không có sự tham gia của User.

Flow cũng đơn giản, Application cần gửi client_id, client_secret là có thể thực hiện tự ủy quyền cho chính mình:

https://OAUTH_SERVER.DOMAIN/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

Sử dụng Access Token

Sau khi đã có thông tin access_token, đọc document xem những API được cung cấp là ta có thể thực hiện một lời gọi API đơn giản với curl như sau:

curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" "https://API_SERVER.DOMAIN/v2/$OBJECT"

Refresh Token Flow

Sau khi access_token hết hạn, nếu bạn sử dụng để gọi API sẽ gặp thông báo lỗi "Invalid Token Error". Đừng lo vì nếu Service hỗ trợ cơ chế Refresh Token, chúng ta có thể dùng refresh_token để "đổi" access_token mới mà không cần thông qua User nữa. Ví dụ về request đổi access_token:

https://OAUTH_SERVER.DOMAIN/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN

Kết luận

  • Qua bài viết này tôi đã giới thiệu với các bạn về OAuth2: khái niệm, các đối tượng tham gia, các luồng hoạt động. Về cơ bản là nặng tính lý thuyết, còn việc triển khai chắc chắn sẽ còn gặp phải nhiều vấn đề nữa mà chúng ta phải xử lý.
  • Với các dịch vụ đã cung cấp sẵn OAuth như kiểu Facebook, Twitter, Google, Github, ... họ đã xây dựng sẵn phần Server và cả những thư viện cũng như bộ SDK cho các nền tảng rồi. Ta chỉ việc lấy bộ thư viện (hoặc SDK) về tích hợp và sử dụng.
  • Trong tình huống các bạn gặp yêu cầu phải tự xây dựng OAuth thì lý thuyết đã có ở trên rồi nhưng mà để thực hiện thì bạn phải tự code.Ý kiến cá nhân tôi thì ngại nhất là phần Client thôi, còn không bạn có thể chỉ cần tự code phần Server và đưa ra các API để Client có thể triển khai theo đúng Flow mà bạn mong muốn.

Truyền token vào trong HTTP Header sử dụng Bearer schema

https://techmaster.vn/posts/33959/khai-niem-ve-json-web-token

Bearer Token Usage

http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html

Refresh Token

http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/

Tham khảo

https://viblo.asia/p/introduction-to-oauth2-3OEqGjDpR9bL