I have faced very weird issue. Here is my Next.js function, that sends request to Nest.js API.
// src/services/logout.service.ts
import React from 'react';
import { ApiClient } from '@api-client';
import { ExceptionHandler } from '@exception-handler';
import { LogoutRequest, LogoutResponse } from '@services/logout/logout.interface';
export const useLogoutService = () => {
const [loading, setLoading] = React.useState(false);
const logout = async (payload: LogoutRequest)
: Promise<LogoutResponse> => {
try {
setLoading(true);
const { data } = await ApiClient.get<LogoutResponse>('/auth/logout', {
headers: { 'x-access-token': `Bearer ${payload.token}` }
});
return data;
} catch (error: any) {
throw ExceptionHandler(error);
} finally {
setLoading(false);
}
};
return { logout, loading };
};
I can tell, that req.headers['x-access-token']
is not an empty string, I have checked that.
// src/pages/api/logout.ts
import { AxiosError } from 'axios';
import { serialize } from 'cookie';
import { NextApiRequest, NextApiResponse } from 'next';
import { Api } from '@api';
export default async (
req: NextApiRequest,
res: NextApiResponse
) => {
try {
const { data, headers } = await Api.get('/user/logout', {
// If I comment out this line, everything will work
headers: { 'x-access-token': req.headers['x-access-token'] }
});
if (headers['set-cookie']) {
res.setHeader('Set-Cookie', serialize(
'_rt', '', {
path: '/',
httpOnly: true,
maxAge: -1
}
));
}
return res.json(data);
} catch (error: any) {
return res
.status((error as AxiosError).response?.status as number)
.json((error as AxiosError).response?.data);
}
};
You see this line, where I pass headers value in order to forward it to back-end - headers: { 'x-access-token': req.headers['x-access-token'] }
. There is where problem starts. If I have this line, I just have pending in the browser all the time and I don't get any response, but when I comment it out, everthing works perfectly fine.
Here is logout function on the back-end:
@UseGuards(JwtGuard)
@Get('logout')
async logout(@UserDecorator() userId: string, @Res() res) {
console.log('userId', userId)
return { message: 'success' };
}
This console.log also works fine, but still no response. Why?
Okay, I have found an issue, it about back-end:
@UseGuards(JwtGuard)
@Get('logout')
// Problem is this res, because of it, return gets "ignored"
async logout(@UserDecorator() userId: string, @Res() res) {
console.log('userId', userId)
return { message: 'success' };
}
I removed this @Res() res
and it started working.