Tránh gọi refreshToken nhiều lần với Axios interceptor
🧠

Tránh gọi refreshToken nhiều lần với Axios interceptor

1. Đặt vấn đề

Chắc hẳn rằng trong quá trình làm việc của anh em front-end đã từng tiếp xúc với hai ông thần là accessTokenrefreshToken phải không nào? Nó đơn giản là xác thực phiên đăng nhập của anh xem còn hạn sử dụng hay không nếu như accessToken hết hạn thì chúng ta sẽ gọi refreshToken để trả về accessToken mới. Vậy nếu nhưng chúng ta có 10 request cùng lúc mà bị hết hạn thì lại gọi 10 lần refreshToken thì thật sự không ổn một chút nào

2. Giải pháp

để giải quyết câu hỏi trên thì chúng ta cần có một ông thần đắc lực để giải vấn đề này đó chính là Axios
Axios là gì: Axios là một thư viện HTTP client dựa trên Promises, giúp gửi và nhận request dễ dàng trong JavaScript (Node.js & trình duyệt).
Ưu điểm và tính năng của Axios:
  • Tạo request từ trình duyệt bằng XMLHttpRequest
  • Tạo request từ node.js bằng http
  • Hỗ trợ Promise API
  • Đón chặn request và response
  • Biến đổi dữ liệu request và response
  • Bãi bỏ request
  • Tự động chuyển đổi cho dữ liệu JSON
  • Hỗ trợ phía client bảo vệ chống lại XSRF

3. Cài đặt và cấu hình Axios

Cài đặt
npm install axios
Cấu hình
import axios from 'axios'; import { API_URL, lOCAL_STORAGE_FIELDS } from '@/constants'; const api = axios.create({ baseURL: API_URL, headers: { 'Content-Type': 'application/json', Accept: 'application/json' }, });
Cấu hình interceptors cho các request
api.interceptors.request.use((config) => { const token = localStorage.getItem(lOCAL_STORAGE_FIELDS.ACCESS_TOKEN) ?? ''; // các request gưởi đi sẽ dược tự động thêm accessToken vào headers config.headers.Authorization = token ? `Bearer ${JSON.parse(token)}` : null; return config; });
Cấu hình interceptors cho các response trả về nếu gặp lỗi 401 Unauthorized
api.interceptors.response.use( async (response) => { const config = response.config; const code = response.data?.code if (code && code === 401) { const newAccessToken handleRequest(); config.headers.Authorization = `Bearer ${newAccessToken}`; return api(config); } return response; }, (error) => { return Promise.reject(error); } );
khi dữ liệu trả về bị lỗi 401 thì Axios sẽ gọi hàm handleRequest để lấy token mới và gán lại Authorization headers cho những request tiếp theo, vậy làm sao để chỉ gọi duy nhất một lần làm mới refreshToken chúng ta hãy cùng nhau tìm hiểu phương pháp dưới đây

4. Ngăn chặn gọi refreshToken khi có nhiều request hết hạn

để ngăn chặn việc gọi nhiều lần refreshToken ta sẽ đặt một cờ là refreshTokenRequest
import axios from 'axios'; import { API_URL, lOCAL_STORAGE_FIELDS } from '@/constants'; let refreshTokenRequest: null | Promise<string> = null; const api = axios.create({ baseURL: API_URL, headers: { 'Content-Type': 'application/json', Accept: 'application/json' }, });
chúng ta sẽ sử dụng cờ refreshTokenRequest trong hàm handleRequest như sau:
const handleRequest = async () => { refreshTokenRequest = refreshTokenRequest ? refreshTokenRequest : refreshToken(); const newAccessToken = await refreshTokenRequest; refreshTokenRequest = null; return newAccessToken; };
giải thích thi response trả về với code 401 thì Axios interceptors sẽ gọi hàm handleRequest ví dụ chúng ta có 10 request bị 401 Unauthorized thì handleRequest sẽ được gọi, nó sẽ kiểm tra rằng refreshTokenRequest đã có giá trị gán hay chưa, nếu chưa thì nó sẽ gán vào đó 1 hàm refreshToken và nếu như đã gán thì nói sẽ chỉ dùng chung duy nhất một lần gọi refreshToken đã được gán vào trước đó. vậy là vấn đề được giải quyết.

5. Kết quả

Thành quả đạt được là dùng nếu có 100 request bị hết hạn đồng thời thì cũng chỉ có duy nhất một lần refreshToken được gọi

6. Tổng kết

Qua bài viết này chúng ta đã tìm hiểu Axios là gì, cách cấu hình Axios với interceptors như thế nào và cách ngăn chặn gọi refreshToken nhiều lần khi có nhiều request hết hạn đồng thời. Nếu bạn thấy bài viết này hữu ích, hãy chia sẻ bài viết này để nhiều người biết đến nhé.

7. Tài liệu tham khảo

    Congratulations!thank for your attention!