Xác thực client bằng JWT hay Session?

Trước khi trả lời câu hỏi nên dùng JWT hay session (phiên làm việc) để xác thực người dùng (client) thì chúng ta cần phân biệt trước hai khái niệm authentication và authorization (xác thực và ủy quyền) trước tiên. Sau đó chúng ta sẽ cũng đi vào chi tiết so sánh hai cách xác thực phổ biến nhất hiện nay. Let’s go!

Xác thực và ủy quyền

Xác thực và ủy quyền là hai khái niệm quan trọng trong lĩnh vực lập trình nói chung và lập trình web nói riêng. Vậy câu hỏi đặt ra (thường thì khi đi phỏng vấn sẽ có nơi hỏi bạn), xác thực và ủy quyền khác nhau như thế nào?

Xác thực (authentication) là quá trình xác thực kiểm tra xem người dùng là ai, trong khi ủy quyền (authorization) là quá trình xác nhận xem người dùng được phép truy cập vào những ứng dụng, tệp tin và dữ liệu cụ thể nào. Làm thế nào để đảm bảo rằng người yêu cầu truy cập tài nguyên thực sự có quyền được truy cập hay không? Và khi danh tính của họ được xác nhận, làm thế nào để kiểm soát những hành động họ có thể thực hiện bên trong đó?

JWT vs. Session - những khác biệt cơ bản

Là hai cách để thực hiện việc xác thực phổ biến hiện nay, khi có nhiều sự lựa chọn, con người ta thường sẽ so sánh cái này với cái tê. Vậy JWT (JSON Web Token) và Session có gì khác nhau, khi nào dùng cái này, cái tê?

Dùng JWT: Ở đây, máy chủ tạo ra một token (một chuỗi ký tự dàiiiii) mà phía client sẽ lưu trữ và “đính kèm” trong header mỗi khi thực hiện request tới máy chủ. Đây là một phương thức không lưu trạng thái (stateless), có nghĩa là máy chủ không cần giữ bản ghi về token này.
Hãy tưởng tượng, bạn cần mua vé đi từ Đà Nẵng ra Hà Nội, và bạn liên hệ công ty X để mua, công ty này có 1 kỹ thuật đặc biệt dùng để in lên tấm vé, khiến nó không thể làm giả được, khi bạn mua vé, họ không cần ghi vào sổ rằng bạn đã mua vé gì cả, chỉ cần lần nào bạn muốn đi thì cầm vé này tới và show ra cho họ xem. Nhờ vào kỹ thuật đặc biệt đã nói, họ biết được bạn đã mua vé của họ, và vé này hợp lệ.

Dùng session: Ngược lại, nó là một phương thức lưu trạng thái (stateful). Máy chủ tạo ra một phiên làm việc (session) cho client và lưu trữ session trên máy chủ. Máy chủ sẽ trả về những định danh đã lưu này vào cookie và đưa cho client nắm, mỗi khi request client sẽ bao gồm cookie trong header và gửi lên máy chủ.
Tương tự ví dụ ở trên, lần này công ty X ko có kỹ thuật đặc biệt gì nữa, họ chỉ đơn giản ghi ra 1 mã bí mật độc nhất vô nhị, ghi vào sổ và ghi ra cho bạn 1 bản sao. Lần này bạn cầm tấm vé đó về, lần sau muốn đi đâu, chỉ cần cầm tấm vé tới, họ sẽ đối chiếu nó với mã bí mật độc nhất vô nhị đã ghi trong sổ, nếu có thì vé bạn hợp lệ.

JWT là gì?

Vậy câu hỏi là, “kỹ thuật đặc biệt” tôi đã ví dụ là gì, làm thế nào 1 chuỗi dài chỉ lưu phía client, server không lưu bất cứ thứ gì, mà lại không thể làm giả được? còn nếu muốn tôi giả chuỗi này được không? Để trả lời nó chúng ta cần biết JWT là gì trước đã.
JWT là viết tắt của “JSON Web Token”. Đây là một tiêu chuẩn mở được sử dụng để truyền thông tin xác thực giữa các bên một cách an toàn dưới dạng một đối tượng JSON. JWT thường được sử dụng trên web và các ứng dụng di động.

JWT được tạo ra bằng cách ký số một JSON object với một chữ ký (secret key) hoặc một khóa công khai/riêng tư. Dưới dạng chuỗi base64. Và JWT chứa ba phần:

Header: Định nghĩa loại token và thuật toán ký (ví dụ HMAC SHA256)

Payload: Chứa các thông tin (claims). Có thể là các thông tin xác thực như tên người dùng, quyền hạn, thời gian hết hạn, và nhiều thông tin khác.

Signature: Kết hợp header, payload và chữ ký để tạo thành một chuỗi xác thực duy nhất. Mục đích để đảm bảo tính toàn vẹn của token và xác nhận rằng nó chưa bị thay đổi trên đường truyền.

image

Và kỹ thuật đặc biệt đó là nhờ vào signature (chữ ký) nên chuỗi này không thể giả mạo và thay đổi, vì chữ ký này được ký bởi một key bí mật lưu trữ trên server.
Về cơ bản có thể làm giả header và payload, nhưng sẽ không thể làm giả được signature nên không thể lừa được server. Nếu bạn cố tình thay đổi nội dung hoặc làm giả nội dung, thì chữ ký này đã thay đổi, không còn như cũ nữa, nên đỉnh cao chỗ này chính là mật mã học.

JWT lifecycle

image

Cơ chế hoạt động

image
  • Sau khi client được xác thực, máy chủ tạo ra một JWT chứa 3 thành phần như đã đề cập
  • JWT token này được gửi lại cho client và client sẽ lưu vào localstorage hoặc cookie
  • Mỗi khi cần request tới server, client sẽ load và đính kèm JWT token này trong header - HTTP Authorization
  • Server xác thực token và cấp quyền truy cập nếu nó hợp lệ.

Ưu điểm

  • Do tính không lưu trạng thái của chúng, JWT lý tưởng cho các hệ thống phân tán.
  • Như bộ trưởng bộ ngoại giao, JWT token có thể dùng cho tất cả ngôn ngữ và framework khác nhau
  • Khi triển khai đúng cách, chúng cung cấp một cách an toàn để xử lý xác thực người dùng.
  • JWT có thể tích hợp với nhiều ngôn ngữ lập trình và framework

Nhược điểm

  • Việc truyền tải JWT token qua HTTPS là cực kỳ quan trọng, vì nếu để bị lộ, thì nó như kiểu trộm biết chìa khóa nhà của bạn vậy
  • Phải nghiên cứu kỹ lưỡng việc lưu trữ token một cách an toàn để ngăn chặn các cuộc tấn công XSS và các lỗ hổng khác
  • Khi một token được tạo ra và gửi đến client, không thể hủy bỏ nó trừ khi nó hết thời gian sống hoặc thay đổi secret key và không thể chủ động force logout được
  • Nếu lưu trữ quá nhiều thông tin người dùng trong token, kích thước của token sẽ phình to ra, nghĩa là chuỗi token sẽ rất dài
  • Thời gian sống của token là cố định, nên nếu set thời gian quá ngắn thì user phải login nhiều lần, tuy nhiên đây không hẳn là nhược điểm, khi thời gian sống ngắn, sẽ giúp bảo mật hơn và chúng ta áp dụng biện pháp refresh token, thì đây không còn là vấn đề nữa

Xác thực dựa trên Session

Xác thực dựa trên phiên(session), thường được gọi là xác thực dựa trên cookie, là một phương pháp mà máy chủ đóng vai trò quan trọng trong việc duy trì các bản ghi xác thực của client.

Cách Hoạt Động:

image
  • Client cung cấp thông tin xác thực, sau đó server sẽ đi kiểm tra
  • Sau khi xác thực thành công, server tạo ra một bản ghi phiên với một định danh duy nhất, định danh client, thời gian bắt đầu phiên, thời gian hết hạn, và có thể bao gồm các thông tin khác như địa chỉ IP và User Agent. Bản ghi này được lưu trữ trong cơ sở dữ liệu
  • Định danh phiên này được gửi lại cho client và lưu trữ dưới dạng cookie trong trình duyệt
  • Mỗi request từ trình duyệt của client tới server sẽ bao gồm cookie này, sau đó server sẽ xác thực phiên bằng cách truy vấn cơ sở dữ liệu. Nếu hợp lệ, yêu cầu được xử lý.

Ưu Điểm

  • Nếu xét trên ứng dụng web truyền thống (server side rendering, …), xác thực dựa trên phiên thường hoạt động hiệu quả và là một lựa chọn phổ biến
  • Bằng cách giữ thông tin xác thực trên máy chủ, việc quản lý phiên trở nên đơn giản hóa. Mỗi phiên đều được duy trì và kiểm soát tại server, giúp đơn giản hóa quá trình quản lý client và phiên làm việc
  • Server có thể kiểm soát quyền truy cập dựa trên thông tin trong phiên, như quyền hạn và thời gian hết hạn. Điều này tạo điều kiện cho việc quản lý an toàn và chặt chẽ về quyền lợi người dùng.
  • Việc thu hồi quyền truy cập có thể thực hiện nhanh chóng bằng cách xóa hoặc vô hiệu hóa bản ghi phiên trên máy chủ. Điều này đảm bảo client mất ngay lập tức quyền truy cập khi cần thiết.

Nhược Điểm

  • Do được lưu vào cơ sở dữ liệu nên khi truy vấn cho mỗi xác thực phiên có thể tạo ra độ trễ, đặc biệt là đối với các ứng dụng có lưu lượng cao => giải quyết bằng cách xài redis, …
  • Việc lưu trữ thông tin phiên trong cookie có thể tạo ra một số vấn đề liên quan đến bảo mật, như khả năng bị đánh cắp thông qua tấn công Cross-Site Scripting (XSS).

Tóm lại

Lựa chọn giữa JWT và xác thực dựa trên phiên (session-based authentication) phụ thuộc vào nhiều yếu tố, và không có một giải pháp duy nhất phù hợp cho mọi tình huống. Tùy vào dự án, chúng ta sẽ xem xét trước khi quyết định chọn cái nào

  • Lựa Chọn JWT:
  • Hệ Thống Phân Tán và Stateless: JWT là lựa chọn tốt khi bạn làm việc với các hệ thống phân tán và cần giữ cho máy chủ không lưu trạng thái (stateless). Nó phù hợp với các ứng dụng API và các ứng dụng Single Page Applications (SPA).
  • Khả Năng Mở Rộng (Scalability): Do tính không lưu trạng thái, JWT có thể giúp giảm áp lực cho cơ sở dữ liệu và mở rộng tốt trong các môi trường có lưu lượng truy cập lớn.
  • Tích Hợp Dễ Dàng: JWT thường dễ tích hợp với các framework và thư viện phổ biến, giúp giảm thời gian triển khai.
  • Lựa Chọn Xác Thực Dựa Trên Phiên:
  • Ứng Dụng Web Truyền Thống: Xác thực dựa trên phiên thường là lựa chọn hàng đầu cho các ứng dụng web truyền thống, nơi trạng thái phiên được duy trì trên máy chủ.

  • Quản Lý Phiên Tập Trung: Nếu bạn cần quản lý phiên tập trung và có kiểm soát chặt chẽ hơn đối với quyền hạn và trạng thái người dùng, xác thực dựa trên phiên có thể là lựa chọn phù hợp.

Và trong vài trường hợp, chúng ta có thể tận dụng kết hợp cả hai loại xác thực, chẳng hạn như sử dụng JWT cho xác thực API và xác thực dựa trên phiên cho các trang web truyền thống.

 Comments
Comment plugin failed to load
Loading comment plugin