使用 CSRF 令牌登录 Cypress

Cypress Login with CSRF token

我真的很想扩展这个话题 "Logging in with CSRF token" 因为我已经用头撞墙好几个星期了,我不能是唯一遇到这个问题的人。所有关于通过 POST 登录或使用 CSRF 登录的话题都不可避免地回到上面的 link.

然而 link 中描述的食谱似乎对我不起作用。他们都假设 CSRF 令牌是在您访问登录页面后创建的。但在我们的网站上,CSRF 令牌仅在您登录后创建。

我用 Postman 进行了测试,在您登录之前 HTML 或 header 中没有 CSRF 令牌。

我还在 Cypress 中使用以下代码对其进行了测试:

describe('gimme dat csrf token', () => {

    it('try to get the csrf token', () => {
        cy.visit(Cypress.env('url'))
        cy.getCookie('YII_CSRF_TOKEN')
            .then(async (c) => {
                cy.log(c.value)
                return c.value
            })

    })
})

这将 return 出错,因为没有 YII_CSRF_TOKEN

Type Error
Cannot read properties of null (reading 'value')

如果我之前添加了一个登录步骤,它将 return CSRF 令牌的值如预期的那样:

import {Login} from "../../pages/login/Login";

describe('gimme dat csrf token', () => {
    
   it('try to get csrf token', () => {
        cy.visit(Cypress.env('url'))
        login.loginCredentials(Cypress.env('userEmail'), Cypress.env('userPass')) //added login
        cy.getCookie('YII_CSRF_TOKEN')
            .then(async (c) => {
                cy.log(c.value)
                return c.value
            })

    })
})

因此上述 link 中的策略 #1(从 HTML 解析令牌)和 #2(从响应 headers 解析令牌)无法工作。

秘诀 #3 也不可行,因为我们有多个实时系统要测试,我们无法公开 /csrf 路由

这只剩下策略 #4,我们一直在使用它。

有什么想法或者我们是否坚持将“手动”登录步骤添加到每个规范文件?

我认为策略 #1 和 #2 依赖于浏览器记住凭据并将它们提供给登录页面,就像 Whosebug 页面一样 - 您不必每次访问都登录。

主要区别在于您使用了 cy.visit() 而不是食谱中显示的 cy.request()

如果您仍然无法成功获取令牌,请尝试使用 cy.session() 登录。它只会在每个会话中调用一次登录函数。

/*
  Enable use of cy.session() and new behavior to handle caching 
  and restoring cookies, localStorage, and sessionStorage.
*/
Cypress.config('experimentalSessionSupport', true)

describe('...', () => {

  beforeEach(() => {
    cy.session(() => {
      login.loginCredentials(Cypress.env('userEmail'), Cypress.env('userPass')) 
    })
  })

  it('try to get csrf token', () => {
    cy.getCookie('YII_CSRF_TOKEN')
      .then((c) => {
        cy.log(c.value)
      })
  })
})