首页 > 解决方案 > Cypress 使用 CSRF 令牌登录

问题描述

我真的很想扩展这个主题“使用 CSRF 令牌登录”,因为我已经把头撞在墙上好几个星期了,而且我不能是唯一一个遇到这个问题的人。所有关于通过 POST 登录或使用 CSRF 登录的话题都不可避免地会回到上面的链接。

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

我用 Postman 进行了测试,在您登录之前,HTML 或标题中没有 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
            })

    })
})

这将返回一个错误,因为没有 YII_CSRF_TOKEN

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

如果我之前添加了登录步骤,它将按预期返回 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
            })

    })
})

因此,上述链接中的策略 #1(从 HTML 解析令牌)和 #2(从响应标头解析令牌)不起作用。

方法 #3 也不可行,因为我们有几个实时系统要测试,我们不能公开 /csrf 路由

这只给我们留下了迄今为止我们一直在使用的策略#4。

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

标签: javascriptauthenticationpostcypresscsrf-token

解决方案


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

主要区别在于您使用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)
      })
  })
})

推荐阅读