Ghi chú về JWT

3493

Bài viết được sự cho phép của tác giả Lưu Bình An

Cơ bản, cần nắm

JWT có thể nhớ nôm na là một JSON đã encrypt => gọi là token, chứa thông tin giúp backend có thể định danh bạn là ai, bạn có quyền gì

Ghi chú về JWT

Nguyên nhân ra đời của JWT là để giải quyết bài toán định danh trong microservice

Phía Back end

Ở phía Backend có 2 vấn đề chính cần quan tâm

  1. Tạo như thế nào
  2. Validate ra làm sao
  Hiểu rõ về JSON là gì? Cách lấy dữ liệu từ JSON
  JSON Web Token (JWT) là gì ?

Việc tạo, thật ra sử dụng những thư viện có sẵn (jsonwebtoken nếu bạn đang dùng Node.js), bạn chỉ cần quan tâm những giá trị đã hoặc muốn nhét thêm trong JSON

Một trường tối quan trong trong JSON là expiresIn, cho phép token sẽ expire sau bao lâu.

Việc validate, thì dùng thư viện nào tạo token, nó sẽ có luôn phương thức để kiểm tra token đó có hợp lệ không.

Phía client dùng SPA

So sánh định danh bằng Session và Token

Giống nhau

  1. Chức năng như nhau, để định danh
  2. Sau khi định danh ở Backend, nó trả về token cho client
  3. Gửi kèm token trên khi muốn dùng một service ở phía backend

Khác nhau

  • Session thì dữ liệu và trạng thái đăng nhập của user được lưu ở bộ nhớ phía server. Không phù hợp với RESTful APIs, mỗi service đều phải stateless, anh là ai, anh từ đâu tới đều phải đưa chứng minh nhân dân chứ chúng tôi không ai rảnh đầu ngồi nhớ mặt hết những ai ra vào service.
  • Session sẽ lưu thông tin về user ở cookie của trình duyệt, vấn đề là các service có thể khác domain, trình duyệt không biết và sẽ không đưa thông tin cookie cho các domain khác

Vấn đề với XSS và CSRF khi dùng JWT

Hết sức thận trọng khi xử lý JWT trong code, token là mồi ngon cho XSS và CSRF

Tuyệt đối không dùng local storage để lưu JWT trên phía frontend. Localstorage có thể được truy xuất bằng JS cùng domain, attacker có thể dùng điểm này để inject thêm mã để lấy local storage. (XSS)

Vì cookie được gửi trên tất cả request, attacker có thể lợi dụng điểm này để gửi một link yêu cầu đổi password (CSRF)

Nếu không còn lựa chọn nào khác, lưu trong bộ nhớ, lưu ý sẽ mất khi user refresh.

Cookie thật ra không phải là không dùng được, nhưng dùng thì phải kiểm tra

  • Dùng httpOnly để cookie không thể được truy cập thông qua JS
  • Dùng SameSite để hạn chế cấp phát cookie đi các domain chỉ định. Nếu phải đưa qua nhiều domain khác nhau, dùng Lax, nó cho phép gọi truyền cookie khác domain nếu là GET

Nếu muốn 100% an toàn tuyệt đối, một số cái giá phải trả, như tắt cross-domain request.

Nếu sử dụng axios, và backend tạo cookie đúng chuẩn, để axios lo phần đó cho an toàn, không cần lo việc xử lý token, cookie một cách thủ công, thiếu chuyên nghiệp.

axios.defaults.withCredentials = true;

Code tham khảo

Có cần HTTPS với JWT?

HTTPS có đảm bảo an toàn tuyệt đối cho site, là yêu cầu bắt buộc khi sử dụng JWT?

100% bảo mật là con số chưa ai giám nhận, hay nói tẹc ra là không thể. Sẽ luôn có đâu đó một con người tài giỏi, thông minh hơn bạn, họ sẽ tìm được cách tấn công phù hợp. May mắn thay những người xuất chúng như vậy họ cũng có đạo đức cao và không rảnh để làm những việc quá tầm thường. Đừng có lên mạng mà “Anh đố chú hack được site anh!”

HTTPS là cơ chế encrypt thông tin đi-về giữa client và server, đảm bảo không có người ngoài nào có thể dòm ngó và đọc được bạn đang gửi gì, nhưng nếu nó đã chui được vào nhà bạn rồi thì thành thật mà nói HTTPS cũng không phải là cánh cửa chỉ có bạn mở được.

Khi nào không nên dùng JWT

Nếu bạn đang muốn sử dụng một stateful backend, JWT là thừa thãi không cần thiết.

JWT sinh ra và phù hợp nhất với stateless API

Thư viện ngon

Vue: vuejs-jwt

React: react-jwt

Angular: angular-jwt

Ghi chú từ bài viết JWT Authentication Best Practices

Bài viết gốc được đăng tải tại vuilaptrinh.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev