When I make a GET request from Angular with a token, in the backend (Node + Express), the GET request hits twice. The first one arrives without the token, and the second one arrives with the token.
When I make the request via Postman, this doesn't happen; only one GET request arrives at the backend with the correct token. When I do it from Angular, the request hits twice. What could be the reason for this?
The GET request from Angular is made like this:
public async getAllIngredients(): Promise<Ingredient[]> {
try {
return await firstValueFrom(
this.http.get<Ingredient[]>(
`${environment.API_URL}/your-chef/ingredients/getIngredients`,
{
withCredentials: true,
}
)
);
} catch (error) {
throw error;
}
}
And in the backend (Node + Express), I have a middleware that checks if the user has a token:
const isAuthenticated = (
req: Request,
res: Response,
next: NextFunction
): void => {
try {
req.session = {};
// We exclude this routes, because otherwise a user would not be able to log in or register because they would not have a token.
const excludedRoutes: string[] = ["/user/login", "/user/register"];
if (excludedRoutes.includes(req.path)) {
return next();
}
console.log(req.method);
// We ignore when try to checkToken because data has been set on login
if (req.path !== "/user/checkToken") {
const data: JwtPayload | string = verifyToken(req.cookies.access_token);
req.session.user = data as IUserSession;
}
next();
} catch (error: any) {
if (error.code === ERRORS.USER.INVALID_TOKEN.code) {
res.status(error.status).send({ message: error.message });
} else {
res.status(500).send({ message: "Error when validate authentication" });
}
}
};
In the backend, I have CORS and middleware configured like this:
app.use(
cors({
origin: process.env.FRONT_END_HOST,
credentials: true,
})
);
app.use(isAuthenticated);
The headers of the two GET requests are as follows: First get (wrogn):
{
"host": "localhost:3000",
"connection": "keep-alive",
"accept": "application/json, text/plain, */*",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "node",
"accept-encoding": "gzip, deflate"
}
Secong get (correct):
{
"host": "localhost:3000",
"connection": "keep-alive",
"sec-ch-ua-platform": "\"Windows\"",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
"accept": "application/json, text/plain, */*",
"sec-ch-ua": "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\"",
"sec-ch-ua-mobile": "?0",
"origin": "http://localhost:4200",
"sec-fetch-site": "same-site",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "http://localhost:4200/",
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": "es,es-ES;q=0.9,ca;q=0.8,en;q=0.7",
"cookie": "access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2Nzc1N2YwZGZlYzMxZDgzMWE3OWQ2ZGQiLCJpYXQiOjE3NDE5NTIwMzAsImV4cCI6MTc0MTk1OTIzMH0.hrOWu0WwxX2d7zNqnv1XPeGKw9tAz6FHgcV1gIpQJ3Q",
"if-none-match": "W/\"128-RGyy7TUC0nG6pCSxdFRvDFMWJbo\""
}
Another relevant detail might be where I call the service and the getIngredients, which is in this onInit:
@Component({
selector: 'ingredients-page',
imports: [SearchInputComponent, TranslateModule, IngredientCardComponent],
templateUrl: './ingredients-page.component.html',
styleUrl: './ingredients-page.component.scss',
})
export class IngredientsPageComponent implements OnInit {
public ingredients: Ingredient[] = [];
/**
* Constructor to import all dependencies
*
* @param {IngredientService} ingredientService
*/
constructor(private ingredientService: IngredientService) {}
public async ngOnInit(): Promise<void> {
try {
console.log('entering the function');
this.ingredients = await this.ingredientService.getAllIngredients();
} catch (error) {
console.log('function error');
throw error;
}
}
}
The error only appears in the Angular server console, but not in the browser. Angular dev client server console: Angular dev client server console output img Browser console: Browser console output img
I think the error is in Angular's onInit, because I tried removing its content and making the getAllIngredients call through a button, and the error didn't appear.
I have tried all possible CORS configurations, but nothing works.
The error was due to Angular SSR being enabled. To fix it, I disabled SSR by removing server
: src/main.server.ts
and changing the outputMode to outputMode
: static
from angular.json.