Cypress + 2 个超级域 + AntiforgeryToken = Cypress 无法重定向
Cypress + 2 Super Domains + AntiforgeryToken = Cypress can't be redirect
我目前正在设置一个 Cypress 解决方案来测试基于 Nuxt 和 .NET 的产品。该产品使用基于 SSO 的登录页面,该页面具有与该产品不同的超级域。
这会导致 cookie 出现问题。实际上,对产品的访问会生成到 SSO 身份验证页面的重定向。并且,在验证身份验证表单之后,由 Cypress 驱动的 Chrome 进入了一个调用循环,其中 cookie 的属性存在错误,特别是 SameSite 属性的值与预期的 SSO 端相比是不正确的。
目前,浏览器中有几个功能被禁用,即:
- SameSiteByDefaultCookies
- CrossSiteDocumentBlockingIfIsolating
- CrossSiteDocumentBlockingIfIsolating
- 隔离来源
- 每个进程一个站点
摘自 cypress/plugins/index.js
on('before:browser:launch', (browser = {}, launchOptions) => {
if (browser.family === 'chromium') {
launchOptions.args.push(
"--disable-features=SameSiteByDefaultCookies,CrossSiteDocumentBlockingIfIsolating,CrossSiteDocumentBlockingIfIsolating,IsolateOrigins,site-per-process"
);
}
console.log(launchOptions.args);
return launchOptions
});
即使禁用 SSO 上的所有保护,也无法使 Cypress 正常工作。
Here is an Excel file 以及通过 Chrome 控制台列出的所有 HTML 请求。该文件描述了 Cypress 驱动的 Chrome 与“经典”Chrome.
之间的差异
注意:在赛普拉斯的配置中添加 "chromeWebSecurity": false,
不会改变任何东西
不完全了解潜在的问题是什么,我无法很好地描述问题。针对各种论坛(包括 Whosebug)上公开的类似问题提出的所有解决方案都不足以解决我的问题。你能帮帮我吗?
提前致谢。
此致,
亚历山大.
这可能是由 10 月 21 日发布的 chrome 94 更新引起的。更新 94 删除了 SameSiteByDefaultCookies
标志,因此修复不再有效。
如果您遇到与我相同的问题,我通过拦截所有请求、检查它们是否具有 set-cookie header(s) 并重写 SameSite 属性来解决它。可能有一种更简洁的方法来做到这一点,因为这确实会使赛普拉斯仪表板有点混乱。您可以将其添加为命令以便于重复使用:
在您的命令文件中:
declare namespace Cypress {
interface Chainable<Subject> {
disableSameSiteCookieRestrictions(): void;
}
}
Cypress.Commands.add('disableSameSiteCookieRestrictions', () => {
cy.intercept('*', (req) => {
req.on('response', (res) => {
if (!res.headers['set-cookie']) {
return;
}
const disableSameSite = (headerContent: string): string => {
return headerContent.replace(/samesite=(lax|strict)/ig, 'samesite=none');
}
if (Array.isArray(res.headers['set-cookie'])) {
res.headers['set-cookie'] = res.headers['set-cookie'].map(disableSameSite);
} else {
res.headers['set-cookie'] = disableSameSite(res.headers['set-cookie']);
}
})
});
});
用法:
it('should login using third party idp', () => {
cy.disableSameSiteCookieRestrictions();
//add test body here
});
或者,运行 它在每次测试之前:
beforeEach(() => cy.disableSameSiteCookieRestrictions());
我终于找到了这个 SSO 身份验证的解决方案。
代码如下:
Cypress.Commands.add('authentificationSSO', (typedeCompte, login) => {
let loginCompte = 'login';
let motDePasseCompte = 'password';
let baseUrlSSO = Cypress.env('baseUrlSSO') ? Cypress.env('baseUrlSSO') : '';
let baseUrl = Cypress.config('baseUrl') ? Cypress.config('baseUrl') : '';
cy.request(
'GET',
baseUrlSSO +
'/Account/Login?${someParameters}%26redirect_uri%3D' +
baseUrl
).then((response) => {
let requestVerificationToken = '0';
let attributsCookieGroupe = [];
let nomCookie = '';
let tokenCookie = '';
const documentHTML = document.createElement('html');
documentHTML.innerHTML = response.body;
attributsCookieGroupe = response.headers['set-cookie'][0].split(';');
const loginForm = documentHTML.getElementsByTagName('form')[0];
const token = loginForm.querySelector('input[name="__RequestVerificationToken"]')?.getAttribute('value');
requestVerificationToken = token ? token : '';
nomCookie = attributsCookieGroupe[0].split('=')[0];
tokenCookie = attributsCookieGroupe[0].split('=')[1];
cy.setCookie(nomCookie, tokenCookie, { sameSite: 'strict' });
cy.request({
method: 'POST',
url:
baseUrlSSO +
'/Account/Login?{someParameters}%26redirect_uri%3D' +
baseUrl,
followRedirect: false,
form: true,
body: {
Login: loginCompte,
Password: motDePasseCompte,
__RequestVerificationToken: requestVerificationToken,
RememberLogin: false
}
});
});
});
我目前正在设置一个 Cypress 解决方案来测试基于 Nuxt 和 .NET 的产品。该产品使用基于 SSO 的登录页面,该页面具有与该产品不同的超级域。
这会导致 cookie 出现问题。实际上,对产品的访问会生成到 SSO 身份验证页面的重定向。并且,在验证身份验证表单之后,由 Cypress 驱动的 Chrome 进入了一个调用循环,其中 cookie 的属性存在错误,特别是 SameSite 属性的值与预期的 SSO 端相比是不正确的。
目前,浏览器中有几个功能被禁用,即:
- SameSiteByDefaultCookies
- CrossSiteDocumentBlockingIfIsolating
- CrossSiteDocumentBlockingIfIsolating
- 隔离来源
- 每个进程一个站点
摘自 cypress/plugins/index.js
on('before:browser:launch', (browser = {}, launchOptions) => {
if (browser.family === 'chromium') {
launchOptions.args.push(
"--disable-features=SameSiteByDefaultCookies,CrossSiteDocumentBlockingIfIsolating,CrossSiteDocumentBlockingIfIsolating,IsolateOrigins,site-per-process"
);
}
console.log(launchOptions.args);
return launchOptions
});
即使禁用 SSO 上的所有保护,也无法使 Cypress 正常工作。
Here is an Excel file 以及通过 Chrome 控制台列出的所有 HTML 请求。该文件描述了 Cypress 驱动的 Chrome 与“经典”Chrome.
之间的差异注意:在赛普拉斯的配置中添加 "chromeWebSecurity": false,
不会改变任何东西
不完全了解潜在的问题是什么,我无法很好地描述问题。针对各种论坛(包括 Whosebug)上公开的类似问题提出的所有解决方案都不足以解决我的问题。你能帮帮我吗?
提前致谢。
此致, 亚历山大.
这可能是由 10 月 21 日发布的 chrome 94 更新引起的。更新 94 删除了 SameSiteByDefaultCookies
标志,因此修复不再有效。
如果您遇到与我相同的问题,我通过拦截所有请求、检查它们是否具有 set-cookie header(s) 并重写 SameSite 属性来解决它。可能有一种更简洁的方法来做到这一点,因为这确实会使赛普拉斯仪表板有点混乱。您可以将其添加为命令以便于重复使用:
在您的命令文件中:
declare namespace Cypress {
interface Chainable<Subject> {
disableSameSiteCookieRestrictions(): void;
}
}
Cypress.Commands.add('disableSameSiteCookieRestrictions', () => {
cy.intercept('*', (req) => {
req.on('response', (res) => {
if (!res.headers['set-cookie']) {
return;
}
const disableSameSite = (headerContent: string): string => {
return headerContent.replace(/samesite=(lax|strict)/ig, 'samesite=none');
}
if (Array.isArray(res.headers['set-cookie'])) {
res.headers['set-cookie'] = res.headers['set-cookie'].map(disableSameSite);
} else {
res.headers['set-cookie'] = disableSameSite(res.headers['set-cookie']);
}
})
});
});
用法:
it('should login using third party idp', () => {
cy.disableSameSiteCookieRestrictions();
//add test body here
});
或者,运行 它在每次测试之前:
beforeEach(() => cy.disableSameSiteCookieRestrictions());
我终于找到了这个 SSO 身份验证的解决方案。
代码如下:
Cypress.Commands.add('authentificationSSO', (typedeCompte, login) => {
let loginCompte = 'login';
let motDePasseCompte = 'password';
let baseUrlSSO = Cypress.env('baseUrlSSO') ? Cypress.env('baseUrlSSO') : '';
let baseUrl = Cypress.config('baseUrl') ? Cypress.config('baseUrl') : '';
cy.request(
'GET',
baseUrlSSO +
'/Account/Login?${someParameters}%26redirect_uri%3D' +
baseUrl
).then((response) => {
let requestVerificationToken = '0';
let attributsCookieGroupe = [];
let nomCookie = '';
let tokenCookie = '';
const documentHTML = document.createElement('html');
documentHTML.innerHTML = response.body;
attributsCookieGroupe = response.headers['set-cookie'][0].split(';');
const loginForm = documentHTML.getElementsByTagName('form')[0];
const token = loginForm.querySelector('input[name="__RequestVerificationToken"]')?.getAttribute('value');
requestVerificationToken = token ? token : '';
nomCookie = attributsCookieGroupe[0].split('=')[0];
tokenCookie = attributsCookieGroupe[0].split('=')[1];
cy.setCookie(nomCookie, tokenCookie, { sameSite: 'strict' });
cy.request({
method: 'POST',
url:
baseUrlSSO +
'/Account/Login?{someParameters}%26redirect_uri%3D' +
baseUrl,
followRedirect: false,
form: true,
body: {
Login: loginCompte,
Password: motDePasseCompte,
__RequestVerificationToken: requestVerificationToken,
RememberLogin: false
}
});
});
});