Refreshing `access_token` on SSR does not work

I've done a plugin/composable based on this doc: https://nuxt.com/docs/guide/recipes/custom-usefetch My composable useCustomFetch is exactly the same as the doc. And here is my customized plugin:
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig();
const authStore = useAuthStore();
let isRefreshing = false;
let refreshAttempts = 0;

const $customFetch = $fetch.create({
baseURL: config.public.apiBaseUrl,

onRequest({ options }) {
const userAccessToken = useCookie("access_token").value;
if (userAccessToken) {
options.headers = options.headers || {};
options.headers["Authorization"] = `Bearer ${userAccessToken}`;
}
},

async onResponseError({ request, response, options }) {
if (response.status === 401 && !isRefreshing) {
isRefreshing = true;
try {
await authStore.refreshAccessToken();
const newAccessToken = useCookie("access_token").value;
if (newAccessToken) {
options.headers = options.headers || {};
options.headers["Authorization"] = `Bearer ${newAccessToken}`;
console.log("Retrying request with new access token");
isRefreshing = false;
refreshAttempts = 0; // Reset attempts on successful refresh
return $fetch(request, options);
}
} catch (e) {
console.error("Token refresh failed:", e);
isRefreshing = false;
refreshAttempts++;
if (refreshAttempts >= 1) {
authStore.logout();
navigateTo("/login");
}
}
} else if (response.status === 401 && isRefreshing) {
navigateTo("/login");
}
return Promise.reject(response._data);
},
});

nuxtApp.provide("customFetch", $customFetch);
});
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig();
const authStore = useAuthStore();
let isRefreshing = false;
let refreshAttempts = 0;

const $customFetch = $fetch.create({
baseURL: config.public.apiBaseUrl,

onRequest({ options }) {
const userAccessToken = useCookie("access_token").value;
if (userAccessToken) {
options.headers = options.headers || {};
options.headers["Authorization"] = `Bearer ${userAccessToken}`;
}
},

async onResponseError({ request, response, options }) {
if (response.status === 401 && !isRefreshing) {
isRefreshing = true;
try {
await authStore.refreshAccessToken();
const newAccessToken = useCookie("access_token").value;
if (newAccessToken) {
options.headers = options.headers || {};
options.headers["Authorization"] = `Bearer ${newAccessToken}`;
console.log("Retrying request with new access token");
isRefreshing = false;
refreshAttempts = 0; // Reset attempts on successful refresh
return $fetch(request, options);
}
} catch (e) {
console.error("Token refresh failed:", e);
isRefreshing = false;
refreshAttempts++;
if (refreshAttempts >= 1) {
authStore.logout();
navigateTo("/login");
}
}
} else if (response.status === 401 && isRefreshing) {
navigateTo("/login");
}
return Promise.reject(response._data);
},
});

nuxtApp.provide("customFetch", $customFetch);
});
Everything is working quite well on CSR, but when I try to refresh my access_token from SSR I have an error that I can't resolve
Nuxt
Custom useFetch in Nuxt · Recipes
How to create a custom fetcher for calling your external API in Nuxt 3.
1 Reply
Chichi / WildSuricate
Here is my pinia auth.ts (with refreshAccessToken function)
Want results from more Discord servers?
Add your server