Я пытаюсь получить доступ к аудиофрагментам в приложении, размещенном в хранилище BLOB-объектов Azure, во время теста Cypress, и я продолжаю получать
«Серверу 403 не удалось аутентифицировать запрос. Убедитесь, что значение заголовка авторизации сформировано правильно, включая подпись».
Приложение работает нормально, когда я использую его вручную через браузер, но не работает во время запуска Cypress.
это моя конфигурация кипариса
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
baseUrl: 'https://tts-sa-dev.azurewebsites.net',
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});
Я использую базовую аутентификацию перед каждым набором тестов
beforeEach(() => cy.authenticate('basic'));
это выглядит так
Cypress.Commands.add('authenticate', (authType: 'basic') => {
if (authType === 'basic') {
const username = 'XXXX';
const password = 'XXXX';
const authHeader = 'Basic ' + btoa(username + ':' + password);
// Intercept all requests and add the Authorization header
cy.intercept('**', (req) => {
req.headers['Authorization'] = authHeader;
});
}
});
Я не уверен, может ли заголовок аутентификации каким-то образом взаимодействовать с подписью Cors из Azure, и, похоже, в stackoverflow больше никто не занимается этим, что я нахожу странным.
Я упростил тест до минимума, но он не смог получить какие-либо данные после вызова конечной точки. Я понимаю, что кипарис, вероятно, изменяет заголовок запроса, но мне не удается зарегистрировать какие-либо различия при его перехвате.
У кого-нибудь есть подобная проблема?
Я сравнил заголовки запросов и обнаружил некоторые расхождения: Отсутствовал заголовок «origin», «accept» представлял собой массив параметров, а «fetch-mode» не являлся Cors, но их корректировка не имела никакого значения.
cy.intercept('*', (req) => {
console.info('Request Headers at Intercept:', req.headers);
req.headers['Accept'] = 'application/json';
req.headers['Origin'] = 'https://xxxx.azurewebsites.net';
req.headers['Sec-Fetch-Mode'] = 'cors';
req.headers['Accept-Language'] = 'cs,en;q=0.9';
});


Я думаю, вам нужно, чтобы имена заголовков начинались с нижнего регистра.
Если вы посмотрите Передача запроса следующему обработчику запроса, он использует строчные буквы authorization, но у вас есть прописные Authorization.
cy.intercept('http://api.company.com/', { middleware: true }, (req) => { req.headers['authorization'] = `token ${token}` })
Если я попробую образец теста с req.headers['Origin'], он пройдет (но не должен)
cy.intercept(/todos/, (req) => {
const defaultHeaders = Cypress._.cloneDeep(req.headers)
console.info('Request Headers at Intercept:', defaultHeaders)
req.headers['Accept'] = 'application/json';
req.headers['Origin'] = 'https://xxxx.azurewebsites.net';
req.headers['Sec-Fetch-Mode'] = 'cors';
req.headers['Accept-Language'] = 'cs,en;q=0.9';
})
.as('request-headers')
cy.window().then(win => {
win.fetch('https://jsonplaceholder.typicode.com/todos/1')
})
cy.wait('@request-headers').then(({request,response}) => {
console.info(request.headers)
expect(request.headers['Origin']).to.eq('https://xxxx.azurewebsites.net')
})
В финале console.info() есть заголовки в верхнем и нижнем регистре для ключей «Origin/origin», что указывает на то, что ключ заголовка чувствителен к регистру.
Origin: "https://xxxx.azurewebsites.net",
origin: "http://localhost:34272"
Если я переключусь на строчные буквы req.headers['origin'], произойдет сбой с ошибкой CORS, что я считаю правильным поведением.
Из этого я пришел к выводу, что правильный формат установки ключей заголовка — использовать строки в нижнем регистре.
Не уверен, что это полный ответ, но он должен помочь вам сделать еще один шаг вперед.
В документации cy.visit() — Добавить базовые заголовки аутентификации показано, как использовать базовую аутентификацию в команде посещения.
cy.visit('https://wile:[email protected]/')
or
cy.visit('https://tts-sa-dev.azurewebsites.net/', {
auth: {
username: 'wile',
password: 'coyote',
},
})
Это должно обеспечить аутентификацию одного тестового теста. Нажмите beforeEach(), чтобы сделать это для каждого теста.
Оберните cy.session, чтобы кэшировать учетные данные для входа.
Cypress.Commands.add('login', (username, password) => {
cy.session([username, password], () => {
cy.visit('https://wile:[email protected]/')
})
})
beforeEach(() => {
cy.login('wile', 'coyote')
})
Попробуйте визит вместо перехвата.
Хорошо, я нашел решение - проблема, похоже, в базовой аутентификации
beforeEach(() => cy.authenticate('basic'));
У Azure есть какая-то проблема с базовой аутентификацией, и она плохо справляется с заголовком авторизации.
Вместо этого я использовал
beforeEach(() => cy.visit('https://username:[email protected]'));
Сейчас работает нормально
Итак, вы сделали то, что предложил TesterDick — cy.visit('https://wile:[email protected]/'). Тогда вам следует принять этот ответ.
честно говоря, я только сейчас заметил вторую часть его ответа, когда вы об этом упомянули :) но вы правы, это правильный подход, и я приветствую его
да, вы правы, ключи заголовков чувствительны к регистру, к сожалению, это не помогает:/