OAuth và JWT: Đừng hiểu nhầm – Vantien’s blog

Từ trước đến nay, khi xây dựng một ứng dụng (Web, Mobile App,…) thì chức năng chung nhất, phổ biến nhất có lẽ là…đăng nhập. Đối với một Web Developer mà nói thì chức năng đăng nhập sử dụng Session hay Cookie có lẽ là quen thuộc hơn cả các bạn nhỉ. Tuy nhiên, việc sử dụng Session/Cookie chỉ có thể áp dụng được trong các website truyền thống, còn đối với API thì chúng ta cần một cách khác. Và thế là vô số các hình thức, cách thức, tiêu chuẩn,… cho việc xác thực người dùng ra đời. Trong bài hôm nay chúng ta hãy cùng tìm hiểu về OAuth và JWT nhé.

Tại sao mình lại đặt tiêu đề là: OAuth và JWT: Đừng hiểu nhầm? Đơn giản thôi, hôm trước mấy anh em đồng nghiệp trong lúc rảnh con nhà bà rỗi thì có tranh luận đến chủ đề OAuth và JWT. Lúc này có vô số câu hỏi được đặt ra như:

  • JWT là gì?
  • OAuth là gì?
  • Nên dùng OAuth hay nên dùng JWT?
  • 2 thằng này có gì giống và khác nhau?
  • Khi nào dùng OAuth và khi nào dùng JWT?

Tuy nhiên, có lẽ bởi vì chưa hiểu rõ được bản chất nên các câu trả lời vẫn chưa thực sự thuyết phục và mọi người vẫn chưa tìm được cái kết đúng nhất. Và thế là bài viết này ra đời… Hi vọng rằng sau khi đọc bài viết này thì mọi người sẽ một cái nhìn đúng đắn nhất về 2 khái niệm này nhé.

JWT?

Khái niệm JWT

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public

JWT.IO

JSON Web Token (JWT) là một tiêu chuẩn mở (RFC 7519), bởi vì là tiêu chuẩn nên nó định nghĩa ra một cách nhanh gọn, khép kín cho việc truyền tải thông tin an toàn giữa các bên bằng cách sử dụng một JSON object. Thông tin này có thể được xác minh và đáng tin cậy vì nó có cả phần chữ ký. JWTs được tạo ra bằng cách sử dụng thuật toán mã hóa bí mật (HMAC) hay một thuật toán mã hóa công khai (RSA hoặc ECDSA).

Mình xin dịch lại theo cách dễ hiểu

Tạo ra JSON Web Token như thế nào?

Như vậy chắc các bạn cũng hiểu rằng bản thân JWT là một tiêu chuẩn để tạo ra một cái token để sử dụng với một mục đích nào đó (thường được sử dụng để xác thực người dùng). Vậy thì nó được tạo ra như thế nào? Mình xin được giải thích đơn giản dưới đây:

Một JSON Web Token được tạo ra bởi 3 thành phần: HEADER, PAYLOAD và SIGNATURE. Trong đó:

Header – bao gồm hai phần chính: loại token và thuật toán đã dùng để mã hóa. Trong đó loại token mặc định là JWT. Thuật toán có thể là HMAC SHA256 – HS256 hoặc RSA.

{
  "typ": "JWT",
  "alg": "HS256"
}

Payload – hay hiểu đơn giản là phần body vậy, đây là nơi chứa những dữ liệu mà chúng ta muốn lưu lại trong JWT.

{
  "id": "1234567890",
  "name": "Tien Nguyen"
}

Singnature là chữ ký trong JWT hay một chuỗi đã được được mã hóa bởi header, payload cùng với một chuỗi bí mật theo nguyên tắc sau:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  <mã bí mật nào đó>
)

Các bạn có thể tìm hiểu, test bằng cách truy cập vào trang của JWT: https://jwt.io/#debugger-io

OAuth?

Khái niệm OAuth

Chắc hẳn các bạn đã đều làm qua (hay ít nhất là sử dụng qua) chức năng đăng nhập thông qua một bên khác (Google, Facebook, Twitter,…) đúng không nhỉ? Hoặc nếu ai đã code Laravel mà có làm website theo mô hình SPA (single page application) thì chắc cũng đã dùng qua package Laravel Passport để xác thực người dùng đúng không. Và đó chính là OAuth đó các bạn (hay chính xác hơn là OAuth2).

OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices.

oauth.net

OAuth 2.0 là một giao thức tiêu chuẩn dành cho việc ủy quyền (authorization). OAuth 2.0 tập trung vào sự đơn giản của nhà phát triển ứng dụng khách trong khi cung cấp các luồng ủy quyền cụ thể cho các ứng dụng web, ứng dụng máy tính để bàn, điện thoại di động và thiết bị phòng khách

Luồng hoạt động

Trong đó:

  • 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.
  • 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) => chính là bạn.
  • 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 Server (API): Nơi lưu trữ thông tin tài khoản của User và được bảo mật.

Như vậy hiểu đơn giản OAuth2 phương thức chứng thực với sự tham gia kết hợp của các thành phần mà mình đã đưa ở trên.

Nên dùng OAuth hay nên dùng JWT?

Có một câu hỏi được đặt ra trong lúc tranh luận đó là Nên dùng OAuth hay nên dùng JWT? và mọi người tranh luật một cách rất sôi nổi về câu hỏi này. Tuy nhiên, theo mình thật ra câu hỏi này hoàn toàn…sai. Tại sao lại sai? Bởi vì 2 thằng này không có nên hay không nên dùng gì cả. Lý do mình sẽ giải thích ở dưới đây:

Như các bạn nhìn luồng hoạt động của OAuth2 có thể thấy bước 4, khi Authorization Server cấp Access Token cho Client. Thì access token này hoàn toàn có thể là…JWT(như Passport đang dùng JWT làm Access Token đó các bạn). Vì sao? Vì bản thân JWT chỉ là một tiêu chuẩn, một cách thức để server tạo ra 1 JSON token dành cho việc xác thực người dùng thôi, nó không quy định cách mà bạn dùng nó để xác thực người dùng như thế nào. Cái quy định phải là OAuth2 các bạn ạ.

Giống như việc bạn di chuyển (xác thực) từ Thanh Xuân về Cầu Giấy, bạn có thể đi bộ, đi xe máy, đi ô tô (OAuth), muốn đi oto thì phải có bằng lái xe (token). Bằng lái đó có thể là A1, A2, B1, B2 gì đó, bạn dùng cái nào đó là tùy các bạn. Bạn không thể hỏi rằng là nên đi bằng oto hay nên đi bằng…bằng lái được đúng không?

Kết luận

Trên đây là bài viết của mình về OAuth và JWT, hi vọng nó giúp ích cho các bạn. Thân ái và quyết thắng!