有没有办法使用 cypress/JS 以编程方式通过 Keycloak 登录应用程序?
Posted
技术标签:
【中文标题】有没有办法使用 cypress/JS 以编程方式通过 Keycloak 登录应用程序?【英文标题】:Is there a way to login into the application through Keycloak programmatically using cypress/JS? 【发布时间】:2021-07-10 04:27:13 【问题描述】:我在 Cypress 中为受 Keycloak 保护的 Web 应用程序编写自动化测试。我已经设法从 keycloak 中检索 jwt 令牌,但我不知道如何处理它。我已经看到,在您登录 keycloak 后,您会被重定向到您的域,并且 keyclock 会设置 cookie、本地存储等。 当您登录他们的页面时,有没有办法以编程方式获得与 keyclock 相同的结果?换句话说,有类似的东西:
cy.getToken().then((token) =>
cy.login(token);
cy.visit(myDomain)
)
【问题讨论】:
【参考方案1】:您可以使用插件cypress-keycloak 来实现。
安装后转到cypress/support/commands.js
并写:
// Using ES6
import 'cypress-keycloak';
OR
// using CommonJS
require('cypress-keycloak');
然后在您的测试中您可以编写(示例取自 cypress-keycloak npm 页面):
describe('thing', () =>
beforeEach(() =>
cy.login(
root: 'https://keycloak.babangsund.com',
realm: 'stage',
username: 'babangsund',
password: 'bacon',
client_id: 'frontend',
redirect_uri: 'https://babangsund.com/',
);
// or login with OTP
cy.loginOTP(
root: 'https://keycloak.babangsund.com',
realm: 'stage',
username: 'babangsund',
password: 'bacon',
client_id: 'frontend',
redirect_uri: 'https://babangsund.com/',
otp_secret: 'OZLDC2HZKM3QUC...', // e.g. 32 chars
otp_credential_id: '5e231f20-8ca7-35e1-20a694b60181ca9', // e.g. 36 chars
);
);
afterEach(() =>
cy.logout(
root: 'https://keycloak.babangsund.com',
realm: 'stage',
redirect_uri: 'https://babangsund.com/',
);
);
);
【讨论】:
感谢您的回答,但对我来说,它似乎不起作用。我之前尝试过其他一些插件,但没有运气。你试过这个插件并且它对你有用吗? ` 您是否正确输入了所有值,如root、realm、用户名、密码等?还有你安装插件后在cypress/support/commands.js
下添加了require('cypress-keycloak');
吗?
是的,我已经完成了他们网站上所说的一切。【参考方案2】:
看看库,cypress-keycloak-commands 是另一个更受欢迎的库(大约是每周下载量的三倍)。
我喜欢它基于配置的方式,并且有 cy.kcFakeLogin()
用于基于夹具的模拟。
如果你想了解Keycloak的详细信息,还有这个博客Cypress.io Keycloak Integration。
如果链接消失,转载以备日后参考
Cypress.Commands.add('kcLogin', (username, password) =>
const kcRoot = 'http://my.keycloak.com';
const kcRealm = 'MYrealm';
const kcClient = 'my-client';
const kcRedirectUri = 'http://localhost:3000/';
const loginPageRequest =
url: `$kcRoot/auth/realms/$kcRealm/protocol/openid-connect/auth`,
qs:
client_id: kcClient,
redirect_uri: kcRedirectUri,
state: createUUID(),
nonce: createUUID(),
response_mode: 'fragment',
response_type: 'code',
scope: 'openid'
;
// Open the KC login page, fill in the form with username and password and submit.
return cy.request(loginPageRequest)
.then(submitLoginForm);
////////////
function submitLoginForm(response)
const _el = document.createElement('html');
_el.innerHTML = response.body;
// This should be more strict depending on your login page template.
const loginForm = _el.getElementsByTagName('form');
const isAlreadyLoggedIn = !loginForm.length;
if (isAlreadyLoggedIn)
return;
return cy.request(
form: true,
method: 'POST',
url: loginForm[0].action,
followRedirect: false,
body:
username: username,
password: password
);
// Copy-pasted code from KC javascript client. It probably doesn't need to be
// this complicated but I refused to spend time on figuring that out.
function createUUID()
var s = [];
var hexDigits = '0123456789abcdef';
for (var i = 0; i < 36; i++)
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
s[14] = '4';
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23] = '-';
var uuid = s.join('');
return uuid;
);
【讨论】:
我也试过这个插件,但没有成功。它只是没有让我登录。你还需要编辑这个代码,“const loginForm = _el.getElementsByTagName('form');”这不起作用。我不得不以另一种方式从这个表单中获取 url。谢谢你的回答。 哦,顺便说一句,here 是getElementsByTagName()
,它应该内置在您的浏览器中。
实际上是JS的一部分,是的,它被浏览器识别,即使它存在,它也找不到标签('form')。所以我不得不用另一种方式找到表格。
好吧,是的,把博客代码当作一个起点,显然需要更多的错误检查。至少它是草根的并且很容易调试(记录响应等)。以上是关于有没有办法使用 cypress/JS 以编程方式通过 Keycloak 登录应用程序?的主要内容,如果未能解决你的问题,请参考以下文章