I'm trying to refresh the access token of a user when it expires by making a request to the backend Express server. To do this, I need to send a request to /auth/updateAccessToken and include the refreshToken cookie, which has the path /auth/updateAccessToken and is httpOnly.
The problem is that I'm using Next.js, and I want to implement this on a server-side page. For this mechanism, I'm using an Axios interceptor, which looks like this:
import axios from 'axios'
import { cookies } from 'next/headers'
const API_URL = process.env.NEXT_PUBLIC_EXPRESS_PATH // Base URL
const axiosInstanceServerSide = axios.create({
baseURL: API_URL,
withCredentials: true
})
// Interceptor that handles authentication; if something fails, it tries to refresh the accessToken and retries the original request, otherwise, it logs out
axiosInstanceServerSide.interceptors.response.use(
response => response, // If the response is successful, return it
async error => {
const originalRequest = error.config
// If the original request returned a 401 error (unauthenticated user)
if (error.response && error.response.status === 401 &&
!originalRequest._retry &&
typeof window === 'undefined') {
originalRequest._retry = true // Prevents an infinite loop
try {
// Correctly access cookies on the server
const cookieStore = await cookies()
// In this part, I can access the accessToken cookie, which has the path '/'
const refreshToken = cookieStore.get('refreshToken') // I try to access the 'refreshToken' cookie (returns undefined)
// Attempt to renew the accessToken by calling the /auth/updateAccessToken route
await axiosInstanceServerSide.post('/auth/updateAccessToken', {}, {
headers: {
Cookie: `refreshToken=${refreshToken}` // Send the cookie directly in the headers
},
withCredentials: true // Ensures that cookies are included in the request
})
// Retry the original request
return axiosInstanceServerSide(originalRequest)
} catch (refreshError) {
// Session logout mechanisms here.
}
}
return Promise.reject(error)
}
)
The issue I'm facing is that I can't seem to access the refreshToken cookie, nor can I automatically include the cookie in the request. This mechanism works correctly on the client side because it automatically adds the cookie.
What am I missing?
I'm using Next for the frontend and Express for the backend. Any help or guidance would be greatly appreciated! Thank you in advance.
I'm trying to refresh the access token of a user when it expires by making a request to the backend Express server. To do this, I need to send a request to /auth/updateAccessToken and include the refreshToken cookie, which has the path /auth/updateAccessToken and is httpOnly.
The problem is that I'm using Next.js, and I want to implement this on a server-side page. For this mechanism, I'm using an Axios interceptor, which looks like this:
import axios from 'axios'
import { cookies } from 'next/headers'
const API_URL = process.env.NEXT_PUBLIC_EXPRESS_PATH // Base URL
const axiosInstanceServerSide = axios.create({
baseURL: API_URL,
withCredentials: true
})
// Interceptor that handles authentication; if something fails, it tries to refresh the accessToken and retries the original request, otherwise, it logs out
axiosInstanceServerSide.interceptors.response.use(
response => response, // If the response is successful, return it
async error => {
const originalRequest = error.config
// If the original request returned a 401 error (unauthenticated user)
if (error.response && error.response.status === 401 &&
!originalRequest._retry &&
typeof window === 'undefined') {
originalRequest._retry = true // Prevents an infinite loop
try {
// Correctly access cookies on the server
const cookieStore = await cookies()
// In this part, I can access the accessToken cookie, which has the path '/'
const refreshToken = cookieStore.get('refreshToken') // I try to access the 'refreshToken' cookie (returns undefined)
// Attempt to renew the accessToken by calling the /auth/updateAccessToken route
await axiosInstanceServerSide.post('/auth/updateAccessToken', {}, {
headers: {
Cookie: `refreshToken=${refreshToken}` // Send the cookie directly in the headers
},
withCredentials: true // Ensures that cookies are included in the request
})
// Retry the original request
return axiosInstanceServerSide(originalRequest)
} catch (refreshError) {
// Session logout mechanisms here.
}
}
return Promise.reject(error)
}
)
The issue I'm facing is that I can't seem to access the refreshToken cookie, nor can I automatically include the cookie in the request. This mechanism works correctly on the client side because it automatically adds the cookie.
What am I missing?
I'm using Next for the frontend and Express for the backend. Any help or guidance would be greatly appreciated! Thank you in advance.
Do you want an easy way? Use Server Actions
First add a new action to access http only cookies
getToken.ts
'use server'
import { cookies } from 'next/headers'
export const getToken = async (cookieName: any) => {
const cookieStore = await cookies()
return cookieStore.get(cookieName as any)?.value
}
Then use this action in your axios interceptor
so instead of this
const cookieStore = await cookies()
const refreshToken = cookieStore.get('refreshToken')
use this
const refreshToken = await getToken('refreshToken')