Я создаю приложение для блога 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 также отправляется. Почему это?
да, но почему файл cookie не отправляется на внутренний экспресс-API? Даже после разрешения «включения» учетных данных и добавления учетных данных: true в серверной части?
Вероятная причина того, что файл cookie не отправляется в Vercel, — это атрибут SameSite. С каким значением (если есть) атрибута SameSite вы создаете рассматриваемый файл cookie? Обратите внимание, что http://localhost:3000 и http://localhost:8000 относятся к одному и тому же сайту, но http://localhost:3000 и https://blog-app-server-red.vercel.app не относятся к одному и тому же сайту.
Так что я могу сделать? где добавить тот же атрибутSite? Можете ли вы предоставить код?
См. Developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…





Эта проблема, по-видимому, связана с политикой 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 в запрос.
Эй, это сработало !! Большое спасибо !
Пожалуйста! Я рад знать, что это сработало.
Если этот ответ помог и сработал, отметьте его, поскольку ответ поможет другим с подобной проблемой @AdityaNagare
Access-Control-Allow-Credentialsне принадлежит запросу; это заголовок ответа.