Похоже, я бьюсь головой об стену ... Я пытался разными способами получить простой вызов Fetch для отправки заголовка авторизации. Вы можете увидеть демо на https://demo -gcf-auth.netlify.com / .
Я получил ряд различных ошибок CORS, но в конечном итоге все они происходят от любого доступа-Control-Allow-Credentials стирается (становится ''
) или, проще говоря, в первую очередь отсутствует заголовок авторизации.
Это простая index.html
, размещенная на Netlify, с Google CloudФункционирует как бэкэнд, который должен получить токен и затем передать его обратно. Конечно, это началось с гораздо более сложной настройки, но я даже не заставляю работать эту крайне минимальную версию. Я также проверил сценарий, используя почти эквивалентный вызов лямбда-функции AWS, которая прекрасно работает. Эта функция имеет автоматически сгенерированный API-шлюз впереди, но я указал некоторые базовые настройки CORS.
Похоже, что шаблон для вызова res.end()
, если вызов имеет метод OPTIONS, был предложен ранее,но я не уверен, почему это было бы хорошим способом справиться с этим. Тем не менее, я не получаю возвращенный токен.
В настоящее время заголовок авторизации, похоже, даже не отправляется, а тем более даже получается в бэкэнде.
Кто-нибудь видит, куда это идетнеправильно?
Пожалуйста, не предлагайте использовать пакет npm cors
, поскольку это не помогает и не делает ничего, что не может быть явно запрограммировано без этой конкретной зависимости.
Я обнаружил связанную проблемупроисходит в https://community.netlify.com/t/authorization-header-is-undefined/4117.
Бэкэнд облачных функций
'use strict';
exports.minimalAuthorization = function(req, res) {
const ORIGIN = req.headers.origin;
console.log('ORIGIN', ORIGIN);
const TOKEN = req.headers.Authorization || req.headers.authorization;
console.log('TOKEN', TOKEN);
const METHOD = req.method;
console.log('METHOD', METHOD);
if (req.method === 'OPTIONS') {
res.end();
} else {
res.set('Access-Control-Allow-Origin', ORIGIN);
res.set('Access-Control-Allow-Credentials', 'true');
res.set('Access-Control-Allow-Methods', '*'); // POST, OPTIONS
res.set('Access-Control-Allow-Headers', '*'); // Origin, Content-Type, Accept, Authorization, authorization
if (TOKEN) {
res.status(200).send(JSON.stringify(TOKEN));
} else res.status(400).send(JSON.stringify('Sorry, no token for you...'));
}
};
Соответствующий раздел HTML-скрипта
<script>
const ENDPOINT =
'https://europe-west1-cloud-developer-basics.cloudfunctions.net/minimalAuthorization';
const TOKEN = `eyJhbGciOiJSUzI1NiIsImtpZCI6ImEwYjQwY2NjYmQ0OWQxNmVkMjg2MGRiNzIyNmQ3NDZiNmZhZmRmYzAiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiTWlrYWVsIFZlc2F2dW9yaSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQUF1RTdtQVhELWtPZHpKbDVDMF9ad3JLY3A3Q2VWWmQzQlp3eG5ydzlicUFTd1UiLCJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vY2xvdWQtZGV2ZWxvcGVyLWJhc2ljcy1lZmUzOSIsImF1ZCI6ImNsb3VkLWRldmVsb3Blci1iYXNpY3MtZWZlMzkiLCJhdXRoX3RpbWUiOjE1NzIyOTc0NTksInVzZXJfaWQiOiJwVERCelM0ZDVyWnJqYjlvMFZLa3g3YmtTZnYyIiwic3ViIjoicFREQnpTNGQ1clpyamI5bzBWS2t4N2JrU2Z2MiIsImlhdCI6MTU3MjI5NzQ2MCwiZXhwIjoxNTcyMzAxMDYwLCJlbWFpbCI6Im1pa2FlbHZlc2F2dW9yaUBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJnb29nbGUuY29tIjpbIjEwNzUwNDM4MzUwMTA4NDY5ODEzNCJdLCJlbWFpbCI6WyJtaWthZWx2ZXNhdnVvcmlAZ21haWwuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoiZ29vZ2xlLmNvbSJ9fQ.LI2ySD6uafnkruEDDmkym6JKoMdhjOEOGKQiytc3SFyeCDERwylqwsmiaCtE7Q6W_FjqrNaAW2rV09rcvuQFPGAMA8uSGiUCdlwau1tBIENHu_HGdW4wI_PWEi6sRmIpbMPTsIPjpcmsSIcpd_WDtz4EldAboXkottFSS7dU81MDbdgrdwKyaq8y-haJqBtr2LAIHy5rg7leSXyY9wqmj9u4iwExWn-pY6BK7dGCEJFTK0_Czvs3qi-0e8bEPmUXwiKzuuMIL_B9l22EHZXqJv0nd9LIzN5_ofyv63U2rG4DbTgNupRAeibhxUO5djVNtgCcFV49618t9ca81d7znQ`;
async function callApiWithToken(token) {
console.log('Calling API with token:', token);
await fetch(ENDPOINT, {
method: 'POST',
credentials: 'include',
headers: {
Authorization: `Bearer ${token}`
}
})
.then(res => res.json())
.catch(error => {
console.error(error);
});
}
callApiWithToken(TOKEN);
</script>
Полностью функциональный лямбда-эквивалент AWS
'use strict';
function minimalAuthorization(event, context) {
const TOKEN = event.headers.Authorization.split('Bearer ')[1];
console.log('TOKEN', TOKEN);
const ORIGIN = event.headers.origin;
console.log('ORIGIN', ORIGIN);
if (TOKEN) {
return {
statusCode: 200,
body: TOKEN,
headers: {
'Access-Control-Allow-Origin': ORIGIN,
'Access-Control-Allow-Credentials': true
}
};
} else
return {
statusCode: 400,
body: 'Sorry, no token for you...',
headers: {
'Access-Control-Allow-Origin': ORIGIN,
'Access-Control-Allow-Credentials': true
}
};
}
exports.handler = async (event, context) => {
return minimalAuthorization(event, context);
};
Конфигурация функции без сервера, AWS Lambda
functions:
minimalAuthorization:
handler: functions/minimalAuthorization.handler
events:
- http:
method: GET
path: minimalAuthorization
cors:
origin: 'https://demo-gcf-auth.netlify.com'
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
- X-Amz-User-Agent
allowCredentials: true