- vừa được xem lúc

Sử dụng Axios interceptor để refresh token cho Next-Auth

0 0 8

Người đăng: Get It Done

Theo Viblo Asia

Khá nhiều developers thích sủ dụng Next-Auth để authenticate cho dự án NextJs, và cũng không ít developers thích sự dụng Axios (một mình hoặc đi kèm thư viện như React-Query). Một ngày đẹp trời bạn nhận ra Next-Auth lưu data ở cookie vậy làm sao để hoạt động với thằng Axios nhỉ? Bài viết này mình sẽ hướng dẫn các bạn sử dụng cobo Next-Auth Axios (Tanstack React Query) để refresh token khi access token hết hạn.

Khi sử dụng Axios đi kèm với Next-Auth chúng ta cần xử lý được 2 phần: Đưa access token vào Header với request interceptor, refresh được token với response interceptor khi access token hết hạn. Next-Auth không hỗ trợ việc update session từ phía client mà ngoài componen nên đẹp nhất chúng ta sẽ tạo ra axios auth dưới dạng 1 hook.

Thiết lập ApiAuth Hook

Khởi tạo axios instance

Tạo file tại lib/api.ts

// lib/api.ts
import { API_URL } from "@/config/const";
import axios from "axios"; export const ApiAuth = axios.create({ baseURL: API_URL,
}); 

Giải thích: File này không có gì đáng nói các bạn nhớ linh hoạt API_URL nhé, đây là enpoint của backend

Api Auth Hook

Tạo file tại hooks/auth/useApiAuth.ts

// hooks/auth/useApiAuth.ts import { useSession } from "next-auth/react";
import { useEffect } from "react";
import { useRefreshToken } from "./useRefreshToken";
import { ApiAuth } from "@/lib/Api"; const useApiAuth = () => { const { data: session } = useSession(); const refreshToken = useRefreshToken(); useEffect(() => { const requestIntercept = ApiAuth.interceptors.request.use( (config) => { if (!config.headers["Authorization"]) { config.headers[ "Authorization" ] = `Bearer ${session?.tokens?.accessToken}`; } return config; }, (error) => Promise.reject(error) ); const responseIntercept = ApiAuth.interceptors.response.use( (response) => response, async (error) => { const prevRequest = error?.config; if (error?.response?.status === 401 && !prevRequest?.sent) { prevRequest.sent = true; await refreshToken(); prevRequest.headers[ "Authorization" ] = `Bearer ${session?.tokens.accessToken}`; return ApiAuth(prevRequest); } return Promise.reject(error); } ); return () => { ApiAuth.interceptors.request.eject(requestIntercept); ApiAuth.interceptors.response.eject(responseIntercept); }; }, [session, refreshToken]); return ApiAuth;
}; export default useApiAuth; 

Giải thích: Hook này thiết lập request interceptor cho axios với access token lấy từ Next-Auth session. Đối với response interceptor nếu nhận về response status 401 thì tiến hành refresh token và gọi lại request

Refresh Token Hook

Tạo file tại hooks/auth/useRefreshToken.ts

// hooks/auth/useRefreshToken.ts
import { Api } from "@/lib/Api";
import { signIn, useSession } from "next-auth/react"; export const useRefreshToken = () => { const { data: session } = useSession(); const refreshToken = async () => { // Gọi tới backend để lấy access token mới và trả về const res = await Api.post("/auth/refresh-token", { refreshToken: session?.tokens.refreshToken, }); if (session) session.tokens.accessToken = res.data.tokens.accessToken; else signIn(); }; return refreshToken;
};

Giải thích: useRefreshToken lấy thông tin refresh token trong Next-Auth session, gọi lên backend để lấy access token mới, cập nhật vào Next-Auth session, và trả về giá trị access token

Sử dụng

Thuần Axios

Lúc này useApiAuth() đã trở thành 1 hook các bạn có thể gọi trong component như bình thường. Ví dụ:

// component posts
import useAxiosAuth from "@lib/hooks/useAxiosAuth"; import { useSession } from "next-auth/react";
import { useState } from "react"; const Posts = () => { const [posts, setPosts] = useState(); const fetchPost = async () => { const res = await axiosAuth.get("/posts"); setPosts(res.data); }; useEffect(() => { fetchPost() }, []} return ( ... );
}; export default HomePage;

Với React Query

Tạo 1 hook kết hợp Api Auth và React Query

// hooks/post/useGetPost.ts
import { useMutation } from "@tanstack/react-query";
import useApiAuth from "@hooks/api/useApiAuth"; export const useGetPosts = () => { const apiAuth = useApiAuth(); return useQuery({ queryKey: ["getPosts"], queryFn: () => Api.get("/posts").then((res) => res.data), });
};

Sử dụng trong component

// component posts
import useGetPosts from "@hooks/post/useGetPost"; const Posts = () => { const { isLoading, data } = useGetPosts(); return ( ... );
};

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tạo sao nên dùng Axios hơn Fetch

Khi làm Frontend, chúng ta luôn phải có yêu cầu request API, hoặc request file từ server, đây đều gọi chung là tạo các HTTP request. Tổng quan và cú pháp.

0 0 174

- vừa được xem lúc

Sử dụng Axios với React

Axios là một HTTP client được viết dựa trên Promises được dùng để hỗ trợ cho việc xây dựng các ứng dụng API từ đơn giản đến phức tạp và có thể được sử dụng cả ở trình duyệt hay Node.js.

0 0 40

- vừa được xem lúc

Giới thiệu về Axios - một HTTP Client dựa trên Promise của Javascript

Tổng quan. Axios là một HTTP client được viết dựa trên Promises được dùng để hỗ trợ cho việc xây dựng các ứng dụng API từ đơn giản đến phức tạp và có thể được sử dụng cả ở trình duyệt hay Node.

0 0 22

- vừa được xem lúc

Redux Saga: 11 - Setup axios client cho dự án reactjs

API module là một trong các module không thể thiếu của một dự án Frontend. Vì chắc chắn dự án của bạn phải cần giao tiếp qua cổng API, nên việc setup http client là cần thiết và quan trọng .

0 0 73

- vừa được xem lúc

Login trong Reactjs sử dụng axios với redux

Giới thiệu. . Cài đặt. Ở đây mình sẽ sử dụng them react-router-dom, material-ui và react-hook-form.

0 0 46

- vừa được xem lúc

Xử lý request và refresh token hiệu quả trong React Js với Axios Interceptors

Mở đầu. Hầu hết một Front-end Developer đều đã từng sử dụng Axios để xử lý các request trong dự án của mình.

0 0 19