Token Authentication, JWT, Access Token và Refresh Token

1. Token Authentication là gì?

 

Token Authentication là cơ chế xác thực sử dụng token để chứng minh danh tính hoặc thông tin xác thực của người dùng hay client khi truy cập các tài nguyên được bảo vệ.

Sau khi người dùng đăng nhập thành công, máy chủ có thể cấp token và gửi về cho client. Khi cần truy cập API, client gửi token kèm theo request để máy chủ kiểm tra tính hợp lệ và xác định danh tính tương ứng.

Tùy thuộc vào cơ chế xác thực, token có thể được gửi trong HTTP header Authorization hoặc được truyền thông qua cookie. Sau khi xác thực token, máy chủ tiếp tục kiểm tra quyền truy cập trước khi xử lý yêu cầu.

Token Authentication hoạt động như thế nào?

  • Bước 1 — Gửi thông tin đăng nhập: Người dùng nhập tên tài khoản và mật khẩu, sau đó gửi thông tin đến máy chủ (Server) qua kết nối HTTPS.
  • Bước 2 — Xác thực và cấp token: Máy chủ kiểm tra thông tin đăng nhập. Nếu hợp lệ, máy chủ có thể cấp token cho client. Token có thể sử dụng định dạng JWT hoặc một định dạng khác, tùy thiết kế của hệ thống.
  • Bước 3 — Lưu trữ token: Máy chủ gửi token về cho trình duyệt hoặc ứng dụng (Client). Client quản lý token theo cơ chế phù hợp. Đối với ứng dụng web, các lựa chọn có thể bao gồm cookie hoặc Web Storage, nhưng mỗi cách có những yêu cầu và rủi ro bảo mật khác nhau.
  • Bước 4 — Gửi token khi gọi API: Khi cần truy cập API được bảo vệ, client gửi token kèm request, thường thông qua header:
    Authorization: Bearer <access_token>

    Với Bearer Token, ứng dụng thường chủ động thêm token vào header. Nếu hệ thống sử dụng cookie xác thực, trình duyệt có thể tự động gửi cookie theo các quy tắc tương ứng.

  • Bước 5 — Xác minh token và kiểm tra quyền: Máy chủ kiểm tra token theo cơ chế xác thực được sử dụng. Nếu token hợp lệ, máy chủ xác định danh tính tương ứng và kiểm tra xem chủ thể đó có quyền thực hiện hành động được yêu cầu hay không. Tùy kiến trúc, máy chủ có thể cần kiểm tra thêm trạng thái token hoặc truy vấn dữ liệu liên quan.

Ưu điểm của Token Authentication

  • Linh hoạt đa nền tảng: Có thể sử dụng trong ứng dụng web, ứng dụng di động và giao tiếp giữa các dịch vụ.
  • Hỗ trợ khả năng mở rộng: Một số cơ chế token, đặc biệt là JWT tự chứa, cho phép máy chủ xác minh token mà không cần tra cứu session riêng cho từng người dùng trong mọi request.
  • Linh hoạt trong thiết kế: Hệ thống có thể kết hợp Access Token và Refresh Token để quản lý quyền truy cập và quá trình làm mới token.

Tuy nhiên, những lợi ích này phụ thuộc vào cách thiết kế hệ thống. Token Authentication không mặc nhiên giúp hệ thống trở thành stateless hoặc an toàn hơn.

2. JWT là gì?

 

JWT (JSON Web Token) là một chuẩn biểu diễn thông tin dưới dạng token, được sử dụng rộng rãi trong các ứng dụng web và di động để truyền tải thông tin giữa các bên.

JWT gồm ba phần: Header, Payload và Signature (chữ ký), được phân tách bằng dấu chấm trong dạng JWT thông dụng.

  • Header: Chứa thông tin về loại token và thuật toán được sử dụng để tạo chữ ký.
  • Payload: Chứa các thông tin cần truyền tải, chẳng hạn như định danh người dùng, thời hạn sử dụng và một số thông tin liên quan đến quyền truy cập.
  • Signature: Được tạo dựa trên Header, Payload và khóa tương ứng với thuật toán ký, giúp kiểm tra tính toàn vẹn và xác thực nguồn gốc của token.

Một đặc điểm của JWT là tính tự chứa (self-contained): token có thể chứa những thông tin cần thiết để máy chủ xác minh token và nhận diện chủ thể mà không cần tra cứu trạng thái phiên đăng nhập trên máy chủ trong mọi yêu cầu.

Tuy nhiên, JWT được ký không có nghĩa là nội dung đã được mã hóa. Người có token thường có thể đọc Payload sau khi giải mã Base64URL. Vì vậy, không nên đưa mật khẩu hoặc thông tin nhạy cảm vào Payload.

Cũng cần phân biệt rằng JWT là một định dạng token, còn Token Authentication là cơ chế xác thực sử dụng token. Không phải mọi token đều là JWT.

3. Access Token và Refresh Token

Access Token là gì?

Access Token là một token được client sử dụng để yêu cầu truy cập các tài nguyên được bảo vệ thông qua API. Access Token thường có định dạng JWT, nhưng cũng có thể là một chuỗi opaque — chuỗi không biểu diễn thông tin theo cấu trúc JWT có thể đọc trực tiếp.

Sau khi đăng nhập thành công, hệ thống có thể cấp Access Token cho client. Khi gọi API, client gửi token kèm request, thường thông qua HTTP header:

Authorization: Bearer <access_token>

Máy chủ sẽ kiểm tra tính hợp lệ của token và xác định chủ thể tương ứng, sau đó kiểm tra quyền truy cập trước khi xử lý yêu cầu.

Refresh Token là gì?

Refresh Token là một loại token được sử dụng để yêu cầu cấp Access Token mới khi Access Token hết hạn hoặc cần được thay mới, giúp người dùng tiếp tục sử dụng hệ thống mà không phải đăng nhập lại mỗi lần.

Refresh Token thường có thời hạn dài hơn Access Token và được gửi đến một endpoint chuyên biệt để làm mới token. Vì Refresh Token có thể được dùng để cấp Access Token mới, hệ thống cần bảo vệ nó cẩn thận, kiểm tra tính hợp lệ và có cơ chế xử lý khi token hết hạn hoặc bị thu hồi.

Access Token và Refresh Token phối hợp như thế nào?

Một luồng hoạt động phổ biến như sau:

  1. Người dùng đăng nhập thành công.
  2. Máy chủ cấp Access Token và có thể cấp thêm Refresh Token.
  3. Client sử dụng Access Token để gọi các API được bảo vệ.
  4. Khi Access Token hết hạn, client gửi Refresh Token đến endpoint làm mới token.
  5. Nếu Refresh Token hợp lệ, máy chủ cấp Access Token mới. Tùy thiết kế, máy chủ cũng có thể cấp Refresh Token mới.
  6. Client tiếp tục sử dụng Access Token mới để gọi API.

Refresh Token không được dùng thay thế Access Token trong các request API thông thường. Hai loại token có mục đích khác nhau và cần được quản lý riêng.

Ngoài cơ chế token, hệ thống cũng có thể sử dụng session-cookie để quản lý phiên đăng nhập. Việc lựa chọn giữa các cơ chế này phụ thuộc vào kiến trúc ứng dụng, yêu cầu bảo mật và cách client giao tiếp với máy chủ, chứ không chỉ phụ thuộc vào việc ứng dụng sử dụng SSR hay CSR.

4. Ví dụ request API sử dụng Bearer Token

Sau khi đăng nhập thành công, client nhận được Access Token và sử dụng token này để gọi API yêu cầu xác thực.

Ví dụ, client muốn lấy danh sách sản phẩm từ endpoint GET /api/products.

Request:

GET /api/products HTTP/1.1
Host: example.com
Authorization: Bearer <access_token>
Accept: application/json

Trong đó:

  • GET /api/products: yêu cầu lấy danh sách sản phẩm.
  • Authorization: HTTP header chứa thông tin xác thực.
  • Bearer <access_token>: cho biết client đang gửi token theo cơ chế Bearer Token.
  • Accept: application/json: cho biết client mong muốn nhận dữ liệu ở định dạng JSON.

Nếu token hợp lệ và người dùng có quyền truy cập, máy chủ có thể trả về:

Response:

HTTP/1.1 200 OK
Content-Type: application/json
{
  "products": [
    {
      "id": 1,
      "name": "Keyboard",
      "price": 500000
    },
    {
      "id": 2,
      "name": "Mouse",
      "price": 250000
    }
  ]
}

Ngược lại, nếu token không hợp lệ hoặc đã hết hạn, máy chủ thường trả về 401 Unauthorized. Nếu token hợp lệ nhưng người dùng không có quyền thực hiện hành động, máy chủ thường trả về 403 Forbidden. Một số hệ thống có thể sử dụng 404 Not Found để tránh tiết lộ sự tồn tại của tài nguyên.

Ví dụ trên sử dụng JWT hay một loại token khác đều có thể được, miễn là API hỗ trợ và xác minh token theo cơ chế tương ứng. Bearer Token là cách sử dụng token; JWT là một định dạng token. Hai khái niệm này không đồng nghĩa với nhau.

5. Ưu điểm, giới hạn và lưu ý bảo mật

Ưu điểm

  • Linh hoạt: Token có thể được sử dụng bởi nhiều loại client như ứng dụng web, ứng dụng di động và các dịch vụ giao tiếp với nhau.
  • Khả năng mở rộng: Với JWT tự chứa, máy chủ có thể xác minh token mà không cần tra cứu session của từng người dùng trong mỗi request, nếu kiến trúc cho phép.
  • Quản lý vòng đời truy cập: Việc kết hợp Access Token và Refresh Token giúp tách biệt token dùng để truy cập API với token dùng để cấp Access Token mới.

Giới hạn

  • Khó thu hồi ngay lập tức: Nếu Access Token vẫn còn hiệu lực, việc đăng xuất hoặc thu hồi token không nhất thiết khiến token đó mất hiệu lực ngay. Hệ thống có thể cần danh sách thu hồi, kiểm tra trạng thái hoặc sử dụng thời hạn token ngắn để xử lý vấn đề này.
  • Cần quản lý vòng đời token: Hệ thống phải xử lý thời hạn hết hạn, làm mới token và các tình huống như Refresh Token bị thu hồi hoặc bị đánh cắp.
  • Không tự động đảm bảo bảo mật: Việc sử dụng token không thay thế cho kiểm tra quyền truy cập, xác thực dữ liệu đầu vào hay các biện pháp bảo vệ API khác.

Lưu ý bảo mật

  • Sử dụng HTTPS: Mã hóa kết nối để giảm nguy cơ token bị đánh cắp khi truyền qua mạng.
  • Bảo vệ nơi lưu trữ token: Lưu token trong localStorage hoặc sessionStorage có nguy cơ bị đánh cắp nếu ứng dụng gặp lỗ hổng XSS. Cookie có thuộc tính HttpOnly, Secure và SameSite phù hợp có thể giảm một số rủi ro, nhưng vẫn cần xem xét nguy cơ CSRF và cách cấu hình cụ thể.
  • Giới hạn thời hạn Access Token: Thời hạn ngắn giúp giảm khoảng thời gian token bị đánh cắp có thể bị lợi dụng.
  • Bảo vệ Refresh Token: Không gửi Refresh Token trong mọi request API thông thường. Cần kiểm tra token khi làm mới, cân nhắc cơ chế xoay vòng (refresh token rotation) và thu hồi token khi phát hiện dấu hiệu bất thường.
  • Kiểm tra quyền ở phía máy chủ: Token hợp lệ không có nghĩa người dùng được phép thực hiện mọi hành động. Máy chủ phải kiểm tra quyền đối với tài nguyên và thao tác cụ thể.
  • Không đưa thông tin nhạy cảm vào JWT Payload: JWT được ký nhưng không mặc định được mã hóa. Người có token thường có thể đọc nội dung Payload, vì vậy không nên lưu mật khẩu hoặc dữ liệu bí mật trong đó.

6. Kết luận

Token Authentication là một cơ chế phổ biến để xác thực các yêu cầu truy cập tài nguyên được bảo vệ. Trong cơ chế này, JWT có thể được sử dụng làm định dạng token, Access Token được dùng để truy cập API, còn Refresh Token hỗ trợ cấp Access Token mới mà không yêu cầu người dùng đăng nhập lại mỗi lần.

Tuy nhiên, việc sử dụng token không tự động bảo đảm hệ thống an toàn hoặc loại bỏ hoàn toàn trạng thái phía máy chủ. Một hệ thống xác thực tốt cần xác minh token đúng cách, kiểm tra quyền truy cập, quản lý thời hạn và thu hồi token, đồng thời bảo vệ token trong quá trình truyền tải và lưu trữ.

Hiểu rõ sự khác nhau giữa Token Authentication, JWT, Bearer Token, Access Token và Refresh Token là nền tảng để tiếp tục tìm hiểu sâu hơn về xác thực và bảo mật API.

Nguồn tham khảo

Bài viết khác

PHP & Laravel Fundamentals

PHP là gì? — Ngôn ngữ lập trình phía máy chủ và vai trò trong phát triển web PHP là gì?   PHP (viết tắt của PHP: Hypertext Preprocessor) là một ngôn ngữ lập trình phía máy chủ, thường được sử dụng để xây dựng website và ứng dụng web động. Trong mô hình phát […]

OpenAPI / Swagger

1. OpenAPI và Swagger là gì? Khi xây dựng backend bằng Go và Gin, developer thường định nghĩa các endpoint như GET /users, POST /users hoặc GET /users/{id}. Tuy nhiên, việc có endpoint hoạt động không đồng nghĩa với việc người khác biết cách sử dụng chúng. OpenAPI là gì? OpenAPI Specification (OAS) là một […]

Gin-Gonic Fundamentals

1. Gin-Gonic là gì? Gin, thường được gọi là Gin-Gonic, là một HTTP web framework viết bằng Go. Framework này cung cấp các công cụ để xây dựng web server và REST API mà không cần tự triển khai toàn bộ việc định tuyến request, đọc dữ liệu HTTP, tạo response hay quản lý middleware. […]

Test Case & Test Plan & Test Data

1. Lời mở đầu và vị trí nền tảng của bộ ba quản lý kiểm thử trong dự án phần mềm Trong quy trình sản xuất phần mềm hiện đại, nếu hoạt động lập trình (Coding) là việc hiện thực hóa các ý tưởng thiết kế thành sản phẩm chạy được, thì hoạt động kiểm […]

Series 3 – JavaScript Fundamentals : JavaScript → DOM

Series 3 — JavaScript Fundamentals   JavaScript → DOM → Async → API   Bài 1. JavaScript & DOM – Từ ngôn ngữ lập trình đến tương tác với giao diện Web   1. JavaScript là gì? Trong quá trình xây dựng website, HTML được sử dụng để tạo cấu trúc nội dung, CSS đảm nhiệm việc […]

Authentication & Authorization

Authentication & Authorization là gì? Authentication (xác thực) và Authorization (phân quyền) là hai khái niệm quan trọng trong bảo mật hệ thống và API. Nói một cách đơn giản: Authentication: Xác minh bạn là ai. Authorization: Xác định bạn được phép làm gì. Ví dụ, khi đăng nhập vào một hệ thống quản lý […]

Leave a Reply

Your email address will not be published. Required fields are marked *