next.js 下一个身份验证登录到Keycloak帐户在Cypress测试

wz3gfoph  于 2023-05-17  发布在  其他
关注(0)|答案(1)|浏览(132)

我正在尝试使用Cypress为我的NextJs应用程序编写一些e2e测试。我正在使用Next Auth登录到我的keycloak帐户使用OAuth。我只向具有特定keycloak角色的用户显示特定的导航栏元素,这就是为什么我为e2e测试创建了一个包含测试用户的测试领域。我的问题是,在测试尝试登录后,我从下一个auth得到一个State cookie was missing.错误,我不知道为什么会发生这种情况。如果我自己尝试测试步骤,它会起作用。
当我在浏览器中执行此操作时进行测试:

  • 打开主页
  • 点击登录
  • 重定向到keycloak
  • 输入用户名
  • 输入密码
  • 点击登录
  • 返回首页返回上一页
  • 登录成功

测试Cypress何时执行此操作:

  • 打开主页
  • 点击登录
  • 重定向到keycloak
  • 输入用户名
  • 输入密码
  • 点击登录
  • 获取重定向到下一个验证错误页
  • 使用State cookie was missing.记录消息
  • 登录失败

是什么导致了柏树的这种行为?
非常感谢帮助:S
编辑:
我发现next-auth.state cookie仍然存在,当登录按钮点击后重新进入我的页面(用cy.getCookies().then(currentSubject => console.log("Cookies:", currentSubject));测试)时,这让我更加困惑,因为下一次认证告诉我它不存在:S
编辑2:
看起来cypress有那个cookie,但它没有到达我的web应用程序,因为应用程序到达的请求不包含任何cookie。

oug3syen

oug3syen1#

我通过重写next-auth的cookie来修复,使它们成为SameSite=None。下面是我使用的代码(在我的例子中通过Auth 0):

function loginViaAuth0Ui(username: string, password: string) {
  cy.intercept("/api/auth/**", (req) =>
      req.on("response", (res) => {
        const setCookies = res.headers["set-cookie"]
        res.headers["set-cookie"] = (
            Array.isArray(setCookies) ? setCookies : [setCookies]
        )
            .filter((x) => x?.startsWith('next-auth'))
            .map((headerContent) => {
                  const replaced = headerContent.replace(
                      /samesite=(lax|strict)/gi,
                      "secure; samesite=none"
                  )
                  // console.log('replaced', headerContent, 'with', replaced)
                  return replaced
                }
            )
      })
  )

  cy.visit('account')
  cy.findByTestId('auth0-button').click()

  cy.origin('https://my-site.uk.auth0.com/', {args: {username, password}}, ({username, password}) => {
    cy.get('input#username').type(username)
    cy.get('input#password').type(password, {log: false})
    cy.contains('button[value=default]', 'Continue').click()
  })

  cy.url().should('include', '/account')
}

TL;DR

该问题与cookie有关,详细描述如下:https://www.tomoliver.net/posts/cypress-samesite-problem(以及我的代码的基础)-总结:next-auth的cookie是SameSite=Lax,由于Cypress在类似iframe的上下文中运行,因此重定向不是“顶级”,因此Chromium阻止了请求。您可以在Chromium请求中的cookie选项卡下的阻止cookie中看到这一点,并给出原因:

示例代码只拦截来自next-auth的响应(拦截更多会更慢),并将cookie重写为SameSite=None,因此它们不会被Chromium阻止。

相关问题