Ошибка при авторизации на JS

Я прописала, что хочу, чтобы каталог был доступен только авторизованному пользователю. Сама авторизация, по идее, отрабатывает, но при попытке попасть на страницу каталога все равно выдает:

{"text":"Пользователь не авторизован!","status":401}

В проекте использую svelte. Функция логина в контроллере:

exports.login = (req, res, next) => {
    passport.authenticate('local',
        (err, user, info) => {

            if (err) return next(err)
            if (!user) return res.status(401).json(new ResObj({
                    text: exceptions.USER_NOT_AUTH,
                }))

            req.login(user, (err) => {
                if (err) return next(err)

                return res.send(new ResObj({
                    text: exceptions.SUCCESS_OPERATION,
                }))
            })
        }
    )(req, res, next)
}

скрипт на странице каталога:

<script>
    import { onMount } from 'svelte';
    import ProductCard from '../../components/product/ProductCard.svelte';

    let products = [];

    onMount(async () => {
        const res = await fetch('http://localhost:3000/product/all', {
            credentials: 'include'
        });

        products = (await res.json()).data;

        // console.log(products);
    });
</script>

Путь, прописанный на сервере:

server.use('/product', isAuthenticated, productRouter)

Функция на проверку авторизации:

exports.isAuthenticated = (req, res, next) => {
    if (req.isAuthenticated()) {
        return next();
    }

    res.send({
        text: exceptions.USER_NOT_AUTH,
        status: 401
    })
};

И сам роутер каталога, если вдруг нужен:

const express = require("express");
const productController = require("../controllers/product.controller")
const productRouter = express.Router();

productRouter.get("/all", productController.getAllProducts);

module.exports = productRouter

Ответы (1 шт):

Автор решения: Богдан Новотарский

Скорее всего, проблема связана с сессией или куками при аутентификации. Разберем возможные причины:

  1. Отсутствие или неправильная передача куков Вы передаете { credentials: 'include' } в fetch, что правильно. Однако браузер будет отправлять куки только в том случае, если:

Сервер правильно их устанавливает (Set-Cookie). На клиенте разрешены сторонние куки (если фронтенд и бэкенд на разных доменах). Запросы идут по одному домену (если localhost, то у вас это работает, но в проде важно). Проверка: В браузере откройте DevTools (F12) → Network → Ваш запрос к /product/all и посмотрите, отправляется ли кука сессии. В DevTools → Application → Cookies проверьте, создается ли кука после логина.

  1. Проблема с сессиями в express-session Если используете express-session, убедитесь, что сервер правильно сохраняет сессию:

Проверьте, как настроен express-session В server.js или app.js должен быть такой код:

const session = require('express-session');
const passport = require('passport');

app.use(session({
    secret: 'your_secret_key',
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: true,
        secure: false,  // Должно быть `true`, если HTTPS
        sameSite: 'lax'  // Или 'none', если фронт и бэк на разных доменах
    }
}));

app.use(passport.initialize());
app.use(passport.session());

Если secure: true, то сессия работать не будет в localhost, потому что там нет HTTPS.

  1. Проблема с req.login Вы вызываете req.login(user, (err) => {...}), но не возвращаете саму сессию клиенту. После успешного логина попробуйте добавить:
req.login(user, (err) => {
    if (err) return next(err);

    res.cookie('connect.sid', req.sessionID, {
        httpOnly: true,
        secure: false, // Если на HTTPS, поменяйте на true
        sameSite: 'lax'
    });

    return res.send(new ResObj({
        text: exceptions.SUCCESS_OPERATION,
    }));
});
  1. Фронтенд и бэкенд на разных доменах Если клиент работает на http://localhost:5173, а сервер на http://localhost:3000, сессии могут не передаваться из-за CORS.

Решение: В server.js добавьте CORS:

const cors = require('cors');

app.use(cors({
    origin: 'http://localhost:5173',
    credentials: true
}));
  1. Проблема с isAuthenticated Попробуйте перед req.isAuthenticated() залогировать сессию:
exports.isAuthenticated = (req, res, next) => {
    console.log('Session:', req.session);
    console.log('User:', req.user);

    if (req.isAuthenticated()) {
        return next();
    }

    res.status(401).json({
        text: exceptions.USER_NOT_AUTH,
        status: 401
    });
};

Если req.user === undefined, значит, сессия не сохраняется.

→ Ссылка