Nextjs Redirect Error
Answered
Silver carp posted this in #help-forum
Silver carpOP
Morning guys, how I use NextJs Redirect inside axios interceptor?
Like
it is giving an error
Like
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
export async function authInterceptorResponseError(error: AxiosError) {
const { response } = error
if (response?.status === 401) {
cookies().delete(AUTH_COOKIE)
if (typeof window === 'undefined') {
redirect('/login')
} else {
window.location.href = '/login'
}
}
return Promise.reject(error)
}it is giving an error
{
digest: 'NEXT_REDIRECT;replace;/login;303;',
mutableCookies: p {
_parsed: Map(3) {
'tenant' => [Object],
'user-info' => [Object],
'auth' => [Object]
},
_headers: Headers {
'set-cookie': 'my-cookies-infos; Path=/, auth=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT'
}
}
}Answered by Silver carp
my interceptor
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
import { AUTH_COOKIE } from '@/utils/constants'
import type { AxiosError, InternalAxiosRequestConfig } from 'axios'
export async function authInterceptorRequest(
config: InternalAxiosRequestConfig,
) {
const token = cookies().get(AUTH_COOKIE)?.value
if (token) {
Object.assign(config.headers || {}, {
authorization: `Bearer ${token}`,
})
}
return config
}
export async function authInterceptorResponseError(error: AxiosError) {
const { response } = error
if (response?.status === 401) {
cookies().delete(AUTH_COOKIE)
if (typeof window !== 'undefined') {
window.location.href = '/login'
}
}
return Promise.reject(error)
}
export async function authInterceptorResponseErrorServerSide(
error: AxiosError,
) {
'use server'
const { response } = error
if (response?.status === 401) {
cookies().delete(AUTH_COOKIE)
if (typeof window === 'undefined') {
redirect('/login')
}
}
}40 Replies
Silver carpOP
But the window is undefined, the request that falls into the interceptor comes from a server action
I'm confused 🤔
@Silver carp But the window is undefined, the request that falls into the interceptor comes from a server action
u should seperate your client and server logic
accessing the window api and redirect at the same time is problematic
u are basically deleting the auth cookie on the serverside and redirecting the user
unless ur your cookie is not http only u can do that on the clientside aswell
Silver carpOP
I don't know how I could do this, within my page.tsx a request is made using server action, which uses axios. What I wanted to do is that when making a request in a server action or on the client side using axios and it returned 401 it would be redirected to login
@Silver carp I don't know how I could do this, within my page.tsx a request is made using server action, which uses axios. What I wanted to do is that when making a request in a server action or on the client side using axios and it returned 401 it would be redirected to login
u dont need axios for server actions, it uses a built in api combined with fetch...
the state is returned from the serveraction
that would be the client approach
u can do the same without returning any error, just delete the cookie and redirect the user directly using a server action (Which can also be problematic)
Silver carpOP
In this case I can't use axios with server actions? I would like to use axios with server action instead of Fetch API
@Silver carp In this case I can't use axios with server actions? I would like to use axios with server action instead of Fetch API
well u can but i dont really know in what case u benefit from that
Silver carpOP
I would like to centralize the axios error response, when giving 401 return to login
@Silver carp I would like to centralize the axios error response, when giving 401 return to login
so i guess it only applies to your login or register endpoint right?
(server action)
Silver carpOP
This would apply to all requests made to my application.
Because there is a middleware that checks the protection of public and private routes based on the token, if the user's token has expired, he will be left without a token and must return to the login
But I understand that I can't use redirect inside the axios interceptor, but I don't see how I could write this logic
@Silver carp But I understand that I can't use redirect inside the axios interceptor, but I don't see how I could write this logic
why dont u redirect using window directly without using redirect from next
remove if else and only have window.location
Silver carpOP
window is undefined
@Silver carp window is undefined
then check if the window is defined and only then href
if (typeof window !== 'undefined')Silver carpOP
But in this case it will never redirect to login
@Silver carp But in this case it will never redirect to login
so is this interceptor designed to only work on the serverside or what
this looks a bit better
maybe u could take a look at that
Silver carpOP
Could I write something like this?
export async function authInterceptorResponseError(error: AxiosError) {
const { response } = error
if (response?.status === 401) {
cookies().delete(AUTH_COOKIE)
if (typeof window !== 'undefined') {
window.location.href = '/login'
}
}
return Promise.reject(error)
}
export async function authInterceptorResponseErrorServerSide(
error: AxiosError,
) {
'use server'
const { response } = error
if (response?.status === 401) {
cookies().delete(AUTH_COOKIE)
if (typeof window === 'undefined') {
redirect('/login')
}
}
}@Silver carp Could I write something like this?
ts
export async function authInterceptorResponseError(error: AxiosError) {
const { response } = error
if (response?.status === 401) {
cookies().delete(AUTH_COOKIE)
if (typeof window !== 'undefined') {
window.location.href = '/login'
}
}
return Promise.reject(error)
}
export async function authInterceptorResponseErrorServerSide(
error: AxiosError,
) {
'use server'
const { response } = error
if (response?.status === 401) {
cookies().delete(AUTH_COOKIE)
if (typeof window === 'undefined') {
redirect('/login')
}
}
}
"use server" should only be defined at the top and also only in server actions
can u share me your src? i will try to fix it for u
Silver carpOP
Yes, just a moment.
I actually won't be able to share all the code, what I can share is
- my page
action.ts
- my page
action.ts
'use server'
import { AxiosError } from 'axios'
import { usersService } from '@/services/http/usersService'
import type { ChangePasswordParams } from '@/services/http/usersService/changePassword'
export async function changePassword(params: ChangePasswordParams) {
if (!Object.values(params).every((value) => Boolean(value))) {
return {
success: false,
message: 'Campos obrigatórios faltantes',
}
}
const { registration, password, newPassword } = params
try {
await usersService.changePassword({ registration, password, newPassword })
return {
success: true,
}
} catch (error) {
console.log('error: ', error)
const message = 'Tente novamente mais tarde'
if (error instanceof AxiosError) {
const { response } = error
return {
success: false,
message: response?.data?.message || message,
}
}
return {
success: false,
message,
}
}
}Silver carpOP
my interceptor
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
import { AUTH_COOKIE } from '@/utils/constants'
import type { AxiosError, InternalAxiosRequestConfig } from 'axios'
export async function authInterceptorRequest(
config: InternalAxiosRequestConfig,
) {
const token = cookies().get(AUTH_COOKIE)?.value
if (token) {
Object.assign(config.headers || {}, {
authorization: `Bearer ${token}`,
})
}
return config
}
export async function authInterceptorResponseError(error: AxiosError) {
const { response } = error
if (response?.status === 401) {
cookies().delete(AUTH_COOKIE)
if (typeof window !== 'undefined') {
window.location.href = '/login'
}
}
return Promise.reject(error)
}
export async function authInterceptorResponseErrorServerSide(
error: AxiosError,
) {
'use server'
const { response } = error
if (response?.status === 401) {
cookies().delete(AUTH_COOKIE)
if (typeof window === 'undefined') {
redirect('/login')
}
}
}Answer
Silver carpOP
From what I saw, there isn't a very nice solution, I'm going to do the redirect inside the server action.
Thank you for your time @gin
Thank you for your time @gin