我尝试在 cypress 测试期间访问托管在 Azure blob 存储上的应用程序中的音频片段,但我不断收到
“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;
});
}
});
我不确定 auth 标头是否可以以某种方式与 azure 的 cors 签名进行交互,而且 stackoverflow 上似乎没有其他人处理这个问题,我觉得这很奇怪。
我已将测试简化为简单的框架,但在调用端点后无法检索任何数据。 我意识到 cypress 可能正在修改请求标头,但在拦截它时我无法记录任何差异。
有人有类似问题吗?
我比较了请求标头,发现存在一些差异: 缺少“origin”标头,“accept”是一组选项,“fetch-mode”是非 cors,但调整它们没有任何区别。
cy.intercept('*', (req) => {
console.log('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.log('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.log(request.headers)
expect(request.headers['Origin']).to.eq('https://xxxx.azurewebsites.net')
})
最后
console.log()
“Origin/origin”键有大写和小写标题,这表明标题键区分大小写。
Origin: "https://xxxx.azurewebsites.net",
origin: "http://localhost:34272"
如果我切换到小写字母
req.headers['origin']
,它会因 CORS 错误而失败,我认为这是正确的行为。
据此我得出结论,设置标头键的正确格式是使用小写字符串。
不确定这是否是完整的答案,但应该会让您更进一步。