使用 Cypress 进行 Auth0 身份验证
Auth0 authentication with Cypress
我正在尝试为 Cypress 创建登录命令,并注意到他们关于如何执行此操作的博客与 Auth0 React SDK. It appears they have used a custom express app to handle the login vs using the SDK to handle this (as per the offical Auth0 documentation) 的预期值不匹配。
Cypress official documentation 生成如下所示的本地存储键值对。
const item = {
body: {
decodedToken: {
claims,
user: { ... },
audience,
client_id,
},
},
expiresAt: exp,
}
window.localStorage.setItem('auth0Cypress', JSON.stringify(item))
然而,由 Auth0 React SDK 创建的生成类似于:
const item = {
body: {
access_token,
audience,
client_id,
decodedToken: {
claims,
user: { ... },
encoded,
header
},
expires_in,
id_token,
scope,
token_type
},
expiresAt: exp
}
window.localStorage.setItem(`@@auth0spajs@@::${client_id}::${audience}::${scope}`, JSON.stringify(item))
我能够使 https://${auth)_domain}/oauth/token
请求正常工作,但是我无法弄清楚如何以适合 Auth0 React SDK 想要的数据结构的方式从响应中获取数据英寸
有人成功过吗?
经过一些探索后,我从 /oauth/token
返回的响应似乎不包含 Auth0 React SDK 在登录时输出值的所有字段。
我还注意到 Auth0 has a guide 关于如何与 Cypress 集成,但是它不使用此 SDK,而是使用 SPA SDK。该指南还使用自定义登录表单,我在其中使用 LockUI。
需要注意的一件事是我没有使用后端进行身份验证(就像在大多数示例中一样)。我按照官方推荐使用 loginWithRedirect
登录。
经过 Auth0 团队的一些调查和帮助,我成功完成了这项工作。
这是我使用的代码:
Cypress.Commands.add("login", () => {
cy.clearLocalStorage();
const email = "";
const password = "";
const client_id = "";
const client_secret = "";
const audience = "";
const scope = "";
cy.request({
method: "POST",
url: "",
body: {
grant_type: "password",
username: email,
password,
audience,
scope,
client_id,
client_secret,
},
}).then(({ body: { access_token, expires_in, id_token, token_type } }) => {
cy.window().then((win) => {
win.localStorage.setItem(
`@@auth0spajs@@::${client_id}::${audience}::${scope}`,
JSON.stringify({
body: {
client_id,
access_token,
id_token,
scope,
expires_in,
token_type,
decodedToken: {
user: JSON.parse(
Buffer.from(id_token.split(".")[1], "base64").toString("ascii")
),
},
audience,
},
expiresAt: Math.floor(Date.now() / 1000) + expires_in,
})
);
cy.reload();
});
});
});
您必须确保您传入的配置与您在 Auth0 提供程序中使用的配置完全相同。
有一次让我失望的是,我还使用了刷新令牌。如果是这种情况,请确保将 offline_access
添加到您的范围。
我有一个 public 存储库来下载一个有效的解决方案 - https://github.com/charklewis/auth0-cypress。
Cypress Real World App, a payment application to demonstrate real-world usage of Cypress testing methods, patterns, and workflows in addition to a Auth0 Authentication Testing Strategies Guide which details the changes in to an Auth0 application and the Cypress Real World App中有一个例子。
对于那些以后遇到这个问题的人。我们创建了一种使用 Cypress 测试 Auth0 的替代方法,它不需要在实际应用程序中更改代码。
我们使用的方法是 运行 公开与 Auth0 相同的 API 的本地服务。我们将此服务打包为 NPM 包。您可以在我们的博客中阅读相关内容 post https://frontside.com/blog/2022-01-13-auth0-simulator/
这是您的测试结果,
import auth0Config from '../../cypress.env.json';
describe('log in', () => {
it('should get token without signing in', () => {
cy.createSimulation(auth0Config)
.visit('/')
.contains('Log out')
.should('not.exist')
.given({
email: 'bob@gmail.com'
})
.login()
.visit('/')
.contains('Log out')
.logout();
});
});
我正在尝试为 Cypress 创建登录命令,并注意到他们关于如何执行此操作的博客与 Auth0 React SDK. It appears they have used a custom express app to handle the login vs using the SDK to handle this (as per the offical Auth0 documentation) 的预期值不匹配。
Cypress official documentation 生成如下所示的本地存储键值对。
const item = {
body: {
decodedToken: {
claims,
user: { ... },
audience,
client_id,
},
},
expiresAt: exp,
}
window.localStorage.setItem('auth0Cypress', JSON.stringify(item))
然而,由 Auth0 React SDK 创建的生成类似于:
const item = {
body: {
access_token,
audience,
client_id,
decodedToken: {
claims,
user: { ... },
encoded,
header
},
expires_in,
id_token,
scope,
token_type
},
expiresAt: exp
}
window.localStorage.setItem(`@@auth0spajs@@::${client_id}::${audience}::${scope}`, JSON.stringify(item))
我能够使 https://${auth)_domain}/oauth/token
请求正常工作,但是我无法弄清楚如何以适合 Auth0 React SDK 想要的数据结构的方式从响应中获取数据英寸
有人成功过吗?
经过一些探索后,我从 /oauth/token
返回的响应似乎不包含 Auth0 React SDK 在登录时输出值的所有字段。
我还注意到 Auth0 has a guide 关于如何与 Cypress 集成,但是它不使用此 SDK,而是使用 SPA SDK。该指南还使用自定义登录表单,我在其中使用 LockUI。
需要注意的一件事是我没有使用后端进行身份验证(就像在大多数示例中一样)。我按照官方推荐使用 loginWithRedirect
登录。
经过 Auth0 团队的一些调查和帮助,我成功完成了这项工作。
这是我使用的代码:
Cypress.Commands.add("login", () => {
cy.clearLocalStorage();
const email = "";
const password = "";
const client_id = "";
const client_secret = "";
const audience = "";
const scope = "";
cy.request({
method: "POST",
url: "",
body: {
grant_type: "password",
username: email,
password,
audience,
scope,
client_id,
client_secret,
},
}).then(({ body: { access_token, expires_in, id_token, token_type } }) => {
cy.window().then((win) => {
win.localStorage.setItem(
`@@auth0spajs@@::${client_id}::${audience}::${scope}`,
JSON.stringify({
body: {
client_id,
access_token,
id_token,
scope,
expires_in,
token_type,
decodedToken: {
user: JSON.parse(
Buffer.from(id_token.split(".")[1], "base64").toString("ascii")
),
},
audience,
},
expiresAt: Math.floor(Date.now() / 1000) + expires_in,
})
);
cy.reload();
});
});
});
您必须确保您传入的配置与您在 Auth0 提供程序中使用的配置完全相同。
有一次让我失望的是,我还使用了刷新令牌。如果是这种情况,请确保将 offline_access
添加到您的范围。
我有一个 public 存储库来下载一个有效的解决方案 - https://github.com/charklewis/auth0-cypress。
Cypress Real World App, a payment application to demonstrate real-world usage of Cypress testing methods, patterns, and workflows in addition to a Auth0 Authentication Testing Strategies Guide which details the changes in to an Auth0 application and the Cypress Real World App中有一个例子。
对于那些以后遇到这个问题的人。我们创建了一种使用 Cypress 测试 Auth0 的替代方法,它不需要在实际应用程序中更改代码。
我们使用的方法是 运行 公开与 Auth0 相同的 API 的本地服务。我们将此服务打包为 NPM 包。您可以在我们的博客中阅读相关内容 post https://frontside.com/blog/2022-01-13-auth0-simulator/
这是您的测试结果,
import auth0Config from '../../cypress.env.json';
describe('log in', () => {
it('should get token without signing in', () => {
cy.createSimulation(auth0Config)
.visit('/')
.contains('Log out')
.should('not.exist')
.given({
email: 'bob@gmail.com'
})
.login()
.visit('/')
.contains('Log out')
.logout();
});
});