Вопрос или проблема
Я сталкиваюсь с постоянной проблемой CORS, работая с HTTPS-функцией Firebase в своем приложении Vite.js на React, особенно при попытке интегрировать OAuth.
Проблема:
При попытке отправить запрос с моего фронтенда на функцию облака Firebase возникает следующая ошибка:callback:1 Доступ к fetch по адресу 'http://127.0.0.1:5001/my-project-id/us-central1/youtube/youtubeaccesstoken' из источника 'http://localhost:5173' был заблокирован политикой CORS: Ответ на предварительный запрос не проходит проверку контроля доступа: Значение заголовка 'Access-Control-Allow-Credentials' в ответе равно '' и должно быть 'true', когда режим проверки подлинности запроса 'include'.
Я установил credentials: ‘include’ в своем запросе fetch, и кажется, что Firebase не возвращает требуемый заголовок Access-Control-Allow-Credentials: true, даже несмотря на то, что я пытался настроить CORS как неявно, так и явно.
Что я пробовал:
- Настройка функции Firebase: Я использовал onRequest Firebase с cors:
true для разрешения CORSconst { onRequest } = require('firebase-functions/v2/https'); exports.youtube = onRequest({ timeoutSeconds: 360, cors: true }, (req, res) => { // Обработка предварительного запроса OPTIONS if (req.method === 'OPTIONS') { res.set('Access-Control-Allow-Origin', 'http://localhost:5173'); res.set('Access-Control-Allow-Methods', 'GET, POST'); res.set('Access-Control-Allow-Headers', 'Authorization, Content-Type'); res.set('Access-Control-Allow-Credentials', 'true'); res.status(204).send(''); return; } // Обработка фактического запроса res.set('Access-Control-Allow-Origin', 'http://localhost:5173'); res.set('Access-Control-Allow-Credentials', 'true'); youtubeService(req, res); });
- Запрос fetch на стороне клиента: Запрос fetch на стороне клиента настроен на включение учетных данных:
fetch('http://127.0.0.1:5001/my-project-id/us-central1/youtube/youtubeaccesstoken', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
code,
state,
userId
}),
});
- Я также пробовал другой подход для своей функции firebase, так как я использую express.
const youtubeService = express();
youtubeService.use(express.json());
youtubeService.use(cookieParser());
const corsOptions = {
origin: "http://localhost:5173", // Использовать конкретный источник вместо true
methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS",
credentials: true, // Разрешить учетные данные
allowedHeaders: ["Content-Type", "Authorization"],
};
youtubeService.use(cors(corsOptions));
//и остальные REST-эндпоинты
exports.youtube = onRequest({
timeoutSeconds: 360,
cors: true,
},
youtubeService
);
Ожидаемое поведение:
Функция Firebase должна разрешать кросс-доменные запросы, возвращая необходимые заголовки CORS, особенно Access-Control-Allow-Credentials: true, при использовании credentials: ‘include’ на фронтенде.
Вещи, которые стоит учитывать:
- Firebase, по идее, должен неявно обрабатывать предварительный запрос, но
я установил это явно, чтобы быть уверенным. - Все остальные заголовки CORS, похоже, работают нормально, кроме
Access-Control-Allow-Credentials
.
.
Ответ или решение
Решение проблемы CORS с заголовком "Access-Control-Allow-Credentials" в Firebase Functions
Когда вы работаете с функциями Firebase в ваших приложениях, правильно настроить CORS (Cross-Origin Resource Sharing) является очень важным аспектом, особенно если вы используете аутентификацию через OAuth. В вашем случае вы столкнулись с ошибкой CORS, которая говорит о том, что заголовок Access-Control-Allow-Credentials
в ответе не установлен на true
, несмотря на ваши попытки правильно настроить эту функциональность.
Основная проблема
Ошибка, которую вы получаете:
Access to fetch at 'http://127.0.0.1:5001/my-project-id/us-central1/youtube/youtubeaccesstoken' from origin 'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.
означает, что ваша конфигурация CORS не корректно отвечает на предзапрос OPTIONS, особенно в отношении заголовка Access-Control-Allow-Credentials
.
Пошаговое решение
- Настройка CORS для Firebase Function
Ваша текущая реализация CORS выглядит довольно близко к правильной, однако стоит убедиться, что все заголовки и методы настроены правильно. Попробуйте следующую структуру, которая включает использование cors
как middleware, если вы используете Express:
const express = require('express');
const cors = require('cors');
const {
onRequest
} = require('firebase-functions/v2/https');
const youtubeService = express();
youtubeService.use(express.json());
const corsOptions = {
origin: "http://localhost:5173", // Укажите конкретный разрешенный источник
methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS",
credentials: true,
allowedHeaders: ["Content-Type", "Authorization"],
};
// Примените middleware CORS
youtubeService.use(cors(corsOptions));
// Обработка OPTIONS предзапроса
youtubeService.options('*', cors(corsOptions));
// Обработка маршрутов
youtubeService.post('/youtubeaccesstoken', (req, res) => {
// Обработайте ваш основной запрос здесь
});
exports.youtube = onRequest({
timeoutSeconds: 360,
}, youtubeService);
- Проверка клиентской части
Убедитесь, что в вашем клиентском коде действительно используется credentials: 'include'
в запросах fetch. Вот пример корректной реализации:
fetch('http://127.0.0.1:5001/my-project-id/us-central1/youtube/youtubeaccesstoken', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
code,
state,
userId
}),
});
Что учитывать
- Если вы передаете куки или используете
credentials: 'include'
, обязательно установите заголовокAccess-Control-Allow-Credentials
с значениемtrue
. - Убедитесь, что предзапросы OPTIONS корректно обрабатываются. В некоторых случаях нужно явно указать этот обработчик.
- Иногда кеширование может привести к неожиданным результатам. Попробуйте использовать
ctrl + F5
для принудительной перезагрузки страницы и сброса кеша. - Проверьте консоль разработчика в браузере на наличие других ошибок CORS и сможете ли вы просмотреть все заголовки ответа.
Заключение
После внесения всех необходимых изменений ваш сервер Firebase должен начать корректно обрабатывать запросы CORS и возвращать требуемые заголовки. Если после этих изменений проблема остается, стоит убедиться, что в настройках Firebase или при работе с различными средами разработки (например, в облаке по сравнению с локальной) нет дополнительных ограничений.