Cookie не получает заголовки запроса после развертывания в Vercel

Я создаю приложение для блога MERN. Первоначально он работал нормально, прежде чем развернуть его в Верселе. Сервер размещался по адресу http://localhost:3000, а часть реагирования клиента размещалась по адресу http://localhost:8000. Серверный файл был развернут на Vercel. Другие маршруты работают нормально, но маршруты, для которых требуются файлы cookie (токен), не работают. Когда я вижу в заголовках запроса, файл cookie не отправляется. Но когда я делаю это перед развертыванием на Vercel, он также отправляет файлы cookie на серверную часть. Почему ошибка?

URL-адрес Vercel для бэкэнда: https://blog-app-server-red.vercel.app/

Код для интерфейса (реакция):

const getProfilePic = async ()=>{
     try {
      const response = await fetch('https://blog-app-server-red.vercel.app/user/'+userId , {
        credentials : 'include',
        headers: {
          "Content-Type": "application/json",
          "Access-Control-Allow-Credentials": true,
        }
      })

Код для бэкэнда (express, mongo):

app.get('/user/:id' , async (req, res)=>{
    try {
                const {token} = req.cookies;
                const {id} = req.params;
                if (token){
                    jwt.verify(token , process.env.JWT_KEY , {} , async (err , info)=>{
                        if (err){
                            throw "Wrong Token ! Access Denied"
                        }
                        const user = await User.findById(id).select('-password');
                        res.status(200).json(user);

                    });
                }
                else{
                    res.status(400).json({error : "Unauthorized !!!"})
                }
            } catch (error) {
                res.status(400).json({error});
            }
})

Промежуточное программное обеспечение CORS (бэкэнд):

app.use(cors({credentials : true , origin : 'http://localhost:3000'}));

Когда то же самое делается для http://localhost:8000 (backend api), все работает нормально, и файл cookie также отправляется. Почему это?

🤔 А знаете ли вы, что...
React предоставляет жизненные циклы компонентов для управления состоянием и поведением.


86
1

Ответ:

Решено

Эта проблема, по-видимому, связана с политикой CORS и файлов cookie, когда ваша серверная часть развернута на Vercel.

Попробуйте эту конфигурацию, чтобы убедиться, что файлы cookie отправляются на сервер правильно.

const allowedOrigins = ['http://localhost:8000', 'https://your-frontend-domain.vercel.app'];

    app.use(cors({
        credentials: true,
        origin: (origin, callback) => {
            if (allowedOrigins.includes(origin) || !origin) {
                callback(null, true);
            } else {
                callback(new Error('Not allowed by CORS'));
            }
        }
    }));

Убедитесь, что файлы cookie, установленные конечной точкой внутреннего сервера, имеют соответствующие атрибуты для отправки в запросах между источниками. Вам необходимо установить атрибут SameSite на None и убедиться, что для атрибута Secure установлено значение true для безопасных контекстов (HTTPS).

res.cookie('token', token, {
    httpOnly: true,
    secure: true,
    sameSite: 'None'
});

В вашем интерфейсном коде все выглядит хорошо, было бы неплохо добавить try-catch для обработки ошибок.

const getProfilePic = async () => {
    try {
        const response = await fetch('https://blog-app-server-red.vercel.app/user/' + userId, {
            credentials: 'include',
            headers: {
                "Content-Type": "application/json",
                "Access-Control-Allow-Credentials": true,
            }
        });

        if (!response.ok) {
            throw new Error('Network response was not ok');
        }

        const data = await response.json();
        return data;
    } catch (error) {
        console.error('There was a problem with your fetch operation:', error);
    }
};

Только если вы используете сеансы, убедитесь, что конфигурация сеанса разрешает файлы cookie из разных источников.

app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true,
    cookie: {
        secure: true, // Ensure this is true if using HTTPS
        sameSite: 'None'
    }
}));

ваш интерфейс и серверная часть должны обслуживаться через HTTPS во время работы. Браузеры блокируют файлы cookie, которые помечены как Secure при отправке через незащищенные соединения.

Используйте инструменты разработчика браузера, чтобы убедиться, что файлы cookie устанавливаются и отправляются правильно. Проверьте в разделе «Приложение» > «Файлы cookie», чтобы убедиться, что токен хранится правильно, а в разделе «Сеть» > «Заголовки» проверьте, включен ли файл cookie в запрос.