typescript - 让 Cypress 正确登录到 Auth0

标签 typescript cypress auth0 react-tsx

我正在使用 cypress 设置一套 E2E 测试。我有一个 React typescript 应用程序,我正在尝试让它与 cypress 一起使用。我面临的主要问题是我使用 Auth0 作为我的身份验证提供程序。这意味着我需要在每次测试之前以编程方式让用户登录。但是我似乎无法获得执行此操作的正确方法。当我尝试它调用回调 url 但它似乎没有对用户进行身份验证,因为他们只是转到一个空白页面?我正在使用 @auth0/auth0-react 包,它有一个用于访问所有 Auth0 数据的钩子(Hook)。

Cypress 命令:

import jwt_decode from 'jwt-decode';

Cypress.Commands.add('login', () => {
    cy.log(`logging in as ${Cypress.env('auth_username')}`);

    cy.request({
        method: 'POST',
        url: Cypress.env('auth_url'),
        body: {
            grant_type: 'password',
            username: Cypress.env('auth_username'),
            password: Cypress.env('auth_password'),
            audience: Cypress.env('auth_audience'),
            scope: 'openid profile email',
            client_id: Cypress.env('auth_client_id'),
            client_secret: Cypress.env('auth_client_secret'),
        },
    }).then(({ body }) => {
        const claims = jwt_decode(body.id_token);
        const { nickname, name, picture, updated_at, email, email_verified, sub, exp } = claims;
        const item = {
            body: {
                ...body,
                decodedToken: {
                    claims,
                    user: {
                        nickname,
                        name,
                        picture,
                        updated_at,
                        email,
                        email_verified,
                        sub,
                    },
                    audience: Cypress.env('auth_audience'),
                    client_id: Cypress.env('auth_client_id'),
                },
            },
            expiresAt: exp,
        };
        window.localStorage.setItem('auth0Cypress', JSON.stringify(item));
    });
});

最佳答案

我刚遇到同样的问题,终于找到了正确的解决方案:

You have to pass the id_token obtained from auth0 token endpoint to your app's callback endpoint as body of POST request

重要:我假设您遵循了 https://docs.cypress.io/guides/testing-strategies/auth0-authentication#Custom-Command-for-Auth0-Authentication 中描述的 auth0 设置或 https://auth0.com/blog/end-to-end-testing-with-cypress-and-auth0/

来源:https://github.com/auth0/express-openid-connect/blob/65bd19eeac63e00e9a5b76973a0a15ecbe2623af/middleware/auth.js#L90第 90 行; https://github.com/auth0/express-openid-connect/blob/65bd19eeac63e00e9a5b76973a0a15ecbe2623af/lib/client.js#L88第 88 行; https://github.com/panva/node-openid-client/blob/main/lib/client.js#L333第 333 行。

工作解决方案:

Cypress.Commands.add("login", (overrides = {}) => {
  const tenantURL = Cypress.env("auth0_tenant_url");
  const options = {
    method: "POST",
    url: `${tenantURL}/oauth/token`,
    body: {
      grant_type: "password",
      username: Cypress.env("auth_username"),
      password: Cypress.env("auth_password"),
      audience: `${tenantURL}/api/v2/`,
      scope: "openid profile email",
      client_id: Cypress.env("auth0_client_id"),
      client_secret: Cypress.env("auth0_client_secret"),
    },
  };
  cy.request(options).then((resp) => {
    const { id_token } = resp.body;
    cy.request({ // this is the crucial part. Passing id_token to callback endpoint 
      method: "POST", // callback endpoint sets the session cookie which is picked up by cypress and used to authenticate subsequent requests
      url: "/callback",
      body: { id_token }, // Must pass only the access_token. Passing full response from oauth causes the 'missing at_hash error'
    });
  });
});

示例 cypress.env.json:

{
  "auth0_tenant_url": "auth0 tenant url",
  "auth0_client_id": "auth0 client id",
  "auth0_client_secret": "auth0 secret",
  "auth_username": "user@fakeemail",
  "auth_password": "password"
}

那么你只需要:

describe("Logged in route test", () => {
  beforeEach(() => {
    cy.login();
    cy.visit("/");
  });

  it("displays content for logged in users", () => {
    cy.get("button[role=buy]").should("exist");
  });
});

您可以在我的 Clampfit 导出器应用程序中查看完整示例:

关于typescript - 让 Cypress 正确登录到 Auth0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66612150/

相关文章:

cypress - 检查 Cypress 中的多个文本项

cypress - 如何使用 Cypress 收听全局事件?

oauth-2.0 - 发送 OAuth token 在 Postman 中有效,但在 RestSharp 中无效

node.js - 将 auth0 集成到 web 应用程序 express/node js 中

javascript - 如何在 react-redux-typescript 中传递 props

typescript - Visual Studio Code 使用 "react-jsx"作为 jsx 值与 create-react-app 的问题

TypeScript 从数组中过滤掉空值

windows - 在 Windows 环境下的 Github Actions 中运行 cypress

vue.js - 具有 Auth0 身份验证的 VueJS 应用程序

Angular 6 不会将 X-XSRF-TOKEN header 添加到 http 请求